Different ways of native inheritance

JavaScript performance comparison

Revision 7 of this test case created by

Preparation code

<script>
   var augment = (function (bind, call) {

    "use strict";

    var bindable = Function.bindable = bind.bind(bind);
    var callable = Function.callable = bindable(call);

    var arrayFrom = Array.from = callable(Array.prototype.slice);
    var ownPropertyOf = Object.ownPropertyOf = callable(Object.hasOwnProperty);

    //Object.defineProperty(Function.prototype, "augment", augmentDescriptor);
    Object.defineProperty(Object.prototype, "augment", { value: augment });

    return callable(augment);

    function augment(body) {
        var base = typeof this === "function" ? this.prototype : this;
        var prototype = Object.create(base);
        body.apply(prototype, arrayFrom(arguments, 1).concat(base));
        if (!ownPropertyOf(prototype, "constructor")) return prototype;
        var constructor = prototype.constructor;
        constructor.prototype = prototype;
        return constructor;
    }
}(Function.bind, Function.call));


function extend() {
    var len = arguments.length;
    var parent = (len > 1) ? arguments[0] : Function.constructor;
    var body = arguments[len - 1];
    body.prototype = parent.prototype;

    var t = function (){
        if (this.init)
            this.init.apply(this, arguments);
    };
    t.prototype = new body(parent.prototype);
    return t;
}
</script>
      
<script>
Benchmark.prototype.setup = function() {
  function A1 () {
    this.pro1 = 'pro1 ';
    this.method1 = function(){ return this.pro1; };
    this.setpro = function(){ this.pro2='edited'; };
  }
  
  function B1() {
    this.pro2 = 'pro2 ';
    this.method2 = function(){return this.pro1 + this.pro2;};
  }
  B1.prototype = new A1();
  
  function C1() {
    this.pro3 = 'pro3 ';
    this.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
  }
  C1.prototype = new B1();
  
  
  
  
  function A2 () {
    this.pro1 = 'pro1 ';
    this.method1 = function(){ return this.pro1; };
    this.setpro = function(){ this.pro2='edited'; };
  }
  
  function B2() {
    this.pro2 = 'pro2 ';
    this.method2 = function(){return this.pro1 + this.pro2;};
    A2.apply(this, arguments);
  }
  
  function C2() {
    this.pro3 = 'pro3 ';
    this.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
    B2.apply(this, arguments);
  }
  
  
  function A3(){}
  A3.prototype.pro1 = 'pro1 ';
  A3.prototype.method1 = function(){ return this.pro1; };
  A3.prototype.setpro = function(){ this.pro2='edited'; };
  
  function B3(){}
  B3.prototype.pro2 = 'pro2 ';
  B3.prototype.method2 = function(){return this.pro1 + this.pro2;};
  
  for (i in A3.prototype)
      B3.prototype[i] = A3.prototype[i]
  
  function C3(){}
  C3.prototype.pro3 = 'pro3 ';
  C3.prototype.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
  
  for (i in B3.prototype)
      C3.prototype[i] = B3.prototype[i];
  
  
  
  function A4() {
    return {
      pro1: 'pro1 ',
      method1: function(){ return this.pro1; },
      setpro: function(){ this.pro2='edited'; }
    };
  }
  function B4() {
    var obj = A4();
    obj.pro2 = 'pro2 ';
    obj.method2 = function(){return this.pro1 + this.pro2;};
    return obj;
  }
  function C4() {
    var obj = B4();
    obj.pro3 = 'pro3 ';
    obj.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
    return obj;
  }
  
  
  
  var A5 = {
    pro1: 'pro1 ',
    method1: function(){ return this.pro1; },
    setpro: function(){ this.pro2='edited'; }
  };
  
  var B5 = Object.create(A5);
  B5.pro2 = 'pro2 ';
  B5.method2 = function(){return this.pro1 + this.pro2;};
  
  var C5 = Object.create(B5);
  C5.pro3 = 'pro3 ';
  C5.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
  
  
  
  
  function A6() {
    return {
      pro1: 'pro1 ',
      method1: function(){ return this.pro1; },
      setpro: function(){ this.pro2='edited'; }
    };
  }
  function B6() {
    var obj = {};
    obj.pro2 = 'pro2 ';
    obj.method2 = function(){return this.pro1 + this.pro2;};
    var a = A6();
    for (i in a)
      obj[i] = a[i];
    return obj;
  }
  function C6() {
    var obj = {};
    obj.pro3 = 'pro3 ';
    obj.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
    var b = B6();
    for (i in b)
      obj[i] = b[i];
    return obj;
  }
  
  var A7 = extend(function (base) {
      this.pro1 = 'pro1 ';
      this.method1 = function() {
          return this.pro1;
      };
      this.setpro = function(){ this.pro2='edited'; };
  });
  var B7 = extend(A7, function(base) {
      this.pro2 = 'pro2 ';
      this.method2 = function() {
          return this.pro1 + this.pro2;
      };
  });
  var C7 = extend(B7, function(base) {
      this.pro3 = 'pro3 ';
      this.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
  });
  
  
  
  
  
  
  
  var A8 = Object.augment(function () {
          this.pro1 = 'pro1 ';
          this.method1 = function() {
              return this.pro1;
          };
          this.setpro = function(){ this.pro2='edited'; };
          this.constructor = function() {};
      });
      var B8 = A8.augment(function() {
          this.pro2 = 'pro2 ';
          this.method2 = function() {
              return this.pro1 + this.pro2;
          };
          this.constructor = function() {};
      });
      var C8 = B8.augment(function() {
          this.pro3 = 'pro3 ';
          this.method3 = function(){return this.pro1 + this.pro2 + this.pro3 + this.method1() + this.method2();};
          this.constructor = function() {};
      });

};
</script>

Test runner

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

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
Pseudo-classical inheritance (through prototyping):
var inst = new C1()
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
Function application or "constructor chaining"
var inst = new C2()
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
Copying prototype iterating the Function.prototype
var inst = new C3()
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
Parasitic inheritance or Power Constructors
var inst = C4();
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
ECMAScript 5th Ed. Object.create method:
var inst = C5;
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
Parasitic inheritance or Power Constructors (Iterating)
var inst = C6();
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
inherit.js
var inst = new C7();
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
pending…
augment.js
var inst = new C8();
inst.setpro();
inst.pro3 = 'changedout ';
inst.newm = function(){ this.pro1 = "# "; };
inst.newm();
inst.method3()
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.

0 Comments