objects 

Send to Kindle
home » snippets » javascript » objects



3 ways of inheritance

Google Closure: goog.inherits

Ref: http://docs.closure-library.googlecode.com/git/closure_goog_base.js.source.html

/**
 * Inherit the prototype methods from one constructor into another.
 *
 * Usage:
 * <pre>
 * function ParentClass(a, b) { }
 * ParentClass.prototype.foo = function(a) { }
 *
 * function ChildClass(a, b, c) {
 *   goog.base(this, a, b);
 * }
 * goog.inherits(ChildClass, ParentClass);
 *
 * var child = new ChildClass('a', 'b', 'see');
 * child.foo(); // works
 * </pre>
 *
 * In addition, a superclass' implementation of a method can be invoked
 * as follows:
 *
 * <pre>
 * ChildClass.prototype.foo = function(a) {
 *   ChildClass.superClass_.foo.call(this, a);
 *   // other code
 * };
 * </pre>
 *
 * @param {Function} childCtor Child class.
 * @param {Function} parentCtor Parent class.
 */
goog.inherits = function(childCtor, parentCtor) {
  /** @constructor */
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.superClass_ = parentCtor.prototype;  // DIFF
  childCtor.prototype = new tempCtor();
  /** @override */
  childCtor.prototype.constructor = childCtor;
};

TypeScript: __extends

function __extends(childCtor, parentCtor) {
    for (var key in parentCtor) {
      if (parentCtor.hasOwnProperty(key)) {
        childCtor[key] = parentCtor[key];
      }
    }
    function tempCtor() {
      this.constructor = childCtor;
    }
    tempCtor.prototype = parentCtor.prototype;
    childCtor.prototype = new tempCtor();
};

Coffeescript: __extends

function __extends(childCtor, parentCtor) {
  for (var key in parentCtor) {
    if (parentCtor.hasOwnProperty(key)) {
      childCtor[key] = parentCtor[key];
    }
  }
  function tempCtor() {
    this.constructor = childCtor;
  }
  tempCtor.prototype = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  childCtor.__super__ = parentCtor.prototype;  // DIFF
  return childCtor;
};

var Animal = (function() {
  function Animal(name) {
    this.name = name;
  }

  Animal.prototype.move = function(meters) {
    return console.log(this.name + (" moved " + meters + "m."));
  };

  return Animal;

})();


var Snake = (function(_super) {
  __extends(Snake, _super);

  function Snake() {
    _ref = Snake.__super__.constructor.apply(this, arguments);
    return _ref;
  }

  Snake.prototype.move = function() {
    console.log("Slithering...");
    return Snake.__super__.move.call(this, 5);
  };

  return Snake;

})(Animal);

var sam = new Snake("Sammy the Python");
sam.move();

Chirayu – prototype chain

Mutating __proto__ is a big big no-no for performance!  Ref __proto__ under IE.

Ref: http://codepen.io/chirayuk/pen/lCkHx

function Animal(name) {
  this.name = name;
};

Animal.prototype.move = function(meters) {
  return console.log(this.name + (" moved " + meters + "m."));
};


// Snake extends Animal
function Snake(name) {
  Animal.apply(this, arguments);
  // Snake.__super__.apply(this, arguments);
};

Snake.prototype = {
  __proto__: Animal.prototype,
  move: function() {
    console.log("Slithering...");
    Animal.prototype.move.call(this, 5);
    // Snake.__super__.prototype.move.call(this, 5);
  }
};
// Snake.__super__ = Animal;

var sammy = new Snake("Sammy the Python");
sammy.move();

Node.js – utils.inherits

exports.inherits = function(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable:    false,
      writable: true,
      configurable: true
    }
  });
};

Misc

function foo() {}
foo.prototype.__proto__ === Object.prototype ; // true