Tag Archives: Function

EcmaScript 6 – Math.hypot()

Many know that JavaScript features vary from browser to browser. In the case of Firefox, there are many new features that have been proposed in EcmaScript 6. One of them is Math.hypot. This function adds up the squares of each argument passed and returns the square-root of that sum. In other words it could be used to find the length of the hypotenuse. Unfortunately, if you want to use this function it is not yet available in most other browsers. That is where the following snippet comes into play:

Math.hypot = Math.hypot || function() {
  var val, ret = 0, args = arguments, i = args.length;
  while (i--) {
    ret += (val = +args[i]) * val;
  }
  return Math.sqrt(ret);
};

Since there are a number of these newly proposed functions, I plan on writing a post to define a safe fallback for each one. Happy coding! 8-)

JavaScript Snippet – String.prototype.count

One string method that I found today in Python is the count function to determine how many times a given substring appears in a string. Below is the equivalent of this function in JavaScript:

String.prototype.count = function(target, start, end) {
  start = start || 0;
  end = end == null ? this.length : end;
  return this.slice(start, end).split(target).length - 1;
};

It is important to note that if you pass a regular expression as the target instead of a string, an incorrect count may be returned. If you need this to work with regular expressions, you can use the following instead:

(function(toString) {
  String.prototype.count = function(target, start, end) {
    start = start || 0;
    end = end == null ? this.length : end;
    var me = this.slice(start, end);
    if (toString.call(target) == '[object RegExp]') {
      if (!target.global) {
        target = new RegExp(target.source,
          (target.ignoreCase ? 'i' : '')
          + (target.multiLine ? 'm' : '')
          + 'g');
      }
      var count = 0;
      me.replace(target, function() {
        count++;
      });
      return count;
    }
    return me.slice(start, end).split(target).length - 1;
  };
})({}.toString);

This function takes one required argument and two optional arguments. The required argument is the substring to be counted. The second argument is the starting point of the string to be searched. The third argument is the ending point of the string to be searched. If negative values are given as the starting or ending point, they will be calculated from the end of the string. Happy coding! 8-)

JavaScript – Creating A JS Library with Optional Prototypes

One thing that I started working on last year, but unfortunately never released, was a version of jPaq which provides the ability to pick whether or not prototypal functions are created. The reason I started working on this was to somewhat satisfy the complaints of those who feel that native prototypes should not be modified. You may wonder how a JavaScript library could be written with the option of adding the corresponding prototypal functions. The following is an example of such a library:

// EXAMPLE JAVASCRIPT LIBRARY USING PROTO
(function(slice, undefined) {
    // Function that adds the specified function as a prototypal function to the
    // specified class with the specified name.
    function proto(theClass, fnName, fn) {
        return theClass.prototype[fnName] = function() {
            return fn.apply(undefined, [this].concat(slice.call(arguments, 0)));
        };
    }

    // Array of prototypal functions to add.
    var protosToAdd = [
        [String, 'lstrip', trimLeft],
        [String, 'rstrip', trimRight],
        [String, 'strip', trim]
    ];

    // Trim functions to be added to jPaq.
    function trimLeft(s) {
        return s.replace(/^\s+/, '');
    }
    function trimRight(s) {
        return s.replace(/\s+$/, '');
    }
    function trim(s) {
        return trimLeft(trimRight(s));
    }

    // Defining the library (in this case jPaq) in the global namespace.  The
    // library comes built-in with the trim functions but if the protoAll
    // function is called the trim function will be prototypalized.
    jPaq = {
        proto: proto,
        trimLeft: trimLeft,
        trimRight: trimRight,
        trim: trim,
        protoAll: function() {
            for (var i = protosToAdd.length; i--;) {
                proto.apply(0, protosToAdd[i]);
            }
        }
    };
})([].slice);

If you were to run the above code block, you would end up defining the scaled-down jPaq library object. On the other hand, at the point no prototypes were actually modified. So, how does this code actually help us? The power is in the proto function which is called by the protoAll function. If you are a developer who doesn’t mind a native prototype being updated (String.prototype in this case), you could execute the following:

jPaq.protoAll();

At this point, executing jPaq.protoAll is the equivalent of the following:

jPaq.proto(String, 'lstrip', jPaq.trimLeft);
jPaq.proto(String, 'rstrip', jPaq.trimRight);
jPaq.proto(String, 'strip', jPaq.trim);

Either one of the above code blocks results in definitions for String.prototype.lstrip, String.prototype.rstrip, and String.prototype.strip. These definitions use the corresponding trim functions defined in the first code block but the only difference is that the context object is passed as the first (and in this case only) argument to the corresponding function. As you may have guessed, this can be very useful, assuming that you design your non-prototypal functions to take the first argument that would be passed in as the context object in a prototypal environment.

Even though this proto function is currently something that I have defined for an example version of jPaq, this could be really be used for almost any JavaScript library. Therefore, if you are creating your own JS library and want to distribute it with the option to add prototypal functions, the following is the function snippet that you can add:

var proto = (function(slice, undefined) {
    return function(theClass, fnName, fn) {
        return theClass.prototype[fnName] = function() {
            return fn.apply(undefined, [this].concat(slice.call(arguments, 0)));
        };
    };
})([].slice);

I hope this helps. 8-)