bind

JavaScript performance comparison

Revision 4 of this test case created by Olmo

Preparation code

<script>
  (function() {
    var slice = [].slice;
 
    function bind1(thisArg) {
      var fn = this,
          args = (arguments.length > 1) ? slice.call(arguments, 1) : null;
 
      return function() {
        var length = arguments.length;
        return (!args && !length)
          ? fn.call(thisArg)
          : fn.apply(thisArg, args && length ? args.concat(slice.call(arguments)) : args || arguments);
      };
    }
 
    function bind2(thisArg) {
      var fn = this,
          args = arguments.length > 1 ? slice.call(arguments, 1) : null;
 
      function F() { }
 
      function bound(){
        var result,
            context = thisArg,
            length = arguments.length;
 
        if (this instanceof bound){
          F.prototype = fn.prototype;
          context = new F;
        }
        result = (!args && !length)
          ? fn.call(context)
          : fn.apply(context, args && length ? args.concat(slice.call(arguments)) : args || arguments);
        return context == thisArg ? result : context;
      }
      return bound;
    }
 
  function bind3(bind){
        var F, result, self = this, args = slice.call(arguments, 1);
        return function bound(){
                if (this instanceof bound){
                        F = function(){};
                        F.prototype = new self;
                        bind = new F;
                }
 
                if (arguments.length) args = args.concat(slice.call(arguments));
                result = args.length ? self.apply(bind, args) : self.call(bind);
                return F ? bind : result;
        };
  };
 
  Function.prototype.bind3 = bind3;
 
  Function.prototype.bind4 = (function(slice, concat) {
 
        return function(bind){
                var fn = this, args = slice.call(arguments, 1);
 
                if (args.length){
                        return function bound1(){
                                if (this instanceof bound1){
                                        F.prototype = self.prototype;
                                        bind = new F;
                                }
                                return fn.apply(bind, arguments.length ? concat.apply(args, arguments) : args);
                        };
                } else {
                        return function bound2(){
                                if (this instanceof bound2){
                                        F.prototype = self.prototype;
                                        bind = new F;
                                }
                                return arguments.length ? fn.apply(bind, arguments) : fn.call(bind);
                        };
                }
        };
 
  })(Array.prototype.slice, Array.prototype.concat);
 
    Function.prototype.bind1 = bind1;
    Function.prototype.bind2 = bind2;
  }());
 
 
</script>
<script>
Benchmark.prototype.setup = function() {
    var fn = function(type) {
      this.type = type;
    };
    var obj = {
      'type': 'bar'
    };
};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Native
var F = fn.bind(obj, 'foo', 'bar');
F();
 
pending…
Old
var F = fn.bind1(obj, 'foo', 'bar');
F();
 
pending…
New
var F = fn.bind2(obj, 'foo', 'bar');
F();
 
pending…
Newer
var F = fn.bind3(obj, 'foo', 'bar');
F();
 
pending…
Optimized
var F = fn.bind4(obj, 'foo', 'bar');
F();
 
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment