1

TypeScript and CoffeeScript both use an __extends function to setup inheritance. Here's the one form TypeScript (CoffeeScript's is very similart).

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};

Why do they need function __() (function ctor() in CoffeeScript)? Why not set the prototype directly:

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];

    d.prototype = new b();
};
just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
  • Because calling `new b()` directly [might have unwanted side effects](http://stackoverflow.com/q/12592913/1048572). – Bergi Jun 17 '14 at 03:01

2 Answers2

1

These three lines a):

    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();

Are almost exactly equivalent to b):

    d.prototype.__proto__ = b.prototype;

And the reason why a) is prefferred is because __proto__ is non standard.

I say almost exactly because in a.) constructor is enumerable where as in b.) it is not modified and therefore stays the way it is (non-enumerable). A better implementation would use Object.create but that is unavailable in ES3 (which is still a compile Target for TypeScript).

basarat
  • 261,912
  • 58
  • 460
  • 511
  • Simply say that it's equivalent to `d.prototype = Object.create(b.prototype);`… – Bergi Jun 17 '14 at 03:00
  • It isn't as d.prototype.constructor gets lost in the object.create ... Which is why you must use a second argument to object.create to restore it. – basarat Jun 17 '14 at 03:13
  • OK, sure, if you want to be nitpicking… What I meant was that you simply might not even mention `__proto__` in your explanation. – Bergi Jun 17 '14 at 03:29
0

John Resig may have answered this in his Simple Javascript Inheritance.

What’s challenging about this, though, is that all we really want is the benefits of ‘instanceof’, not the whole cost of instantiating a Person object and running its constructor.

By creating an intermediate ctor or __ object, the __extends method does not have to call the base class constructor to just to setup the prototype!

just.another.programmer
  • 8,579
  • 8
  • 51
  • 90