JavaScript Inheritance and Super Constructor

I found and adapted the extension function of the JavaScript class from coffeescript:

var extend = (function() { var hasProp = Object.prototype.hasOwnProperty; function ctor(child) { this.constructor = child; } return function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) { child[key] = parent[key]; } } ctor.prototype = parent.prototype; child.prototype = new ctor(child); child.__super__ = parent.prototype; // child.prototype.__super__ = parent.prototype; // better? return child; }; })(); 

I am wondering if there is a reason why they used child.__super__ instead of child.prototype.__super__ (see line with code comments).

I like the commented version more because:

  • You can access super properties using this.__super__.propertyName ClassName.__super__.propertyName instead of ClassName.__super__.propertyName . This way you have no redundancy in class names.

  • This is even more important for nested inheritance, since you can use this.__super__.__super__.propertyName ClassName.__super__.constructor.__super__.propertyName instead of ClassName.__super__.constructor.__super__.propertyName

I see no reason for this, but you can even call the "static" functions in a "static" way:

 ClassName.prototype.__super__.constructor.staticMethod() 

Are there any flaws in my version that I could miss?

EDIT: I fixed the line to var hasProp = Object.prototype.hasOwnProperty;

0
source share
1 answer

Because you should not use __super__ in your code at all.

This is a compiler artifact, every use of the macro super / keyword / whatever it will be compiled into

 ClassName.__super__.methodName.call(this, …) // or ClassName.__super__.methodName.apply(this, …) // or, in static class functions even ClassName.__super___.constructor.functionName.call(this, …) 

They do not trust the dynamic this binding that you proposed to use ( this.__super__ ), they rather went to the parent's static link. In fact, it would be nice not to use the property at all, but only the local variable super in its scope of the module.


In addition, this.__super__ will not work in the inherited method:

 function A() { } A.prototype.method = function() { console.log("works") }; function B() { A.call(this); } B.prototype = Object.create(A.prototype); B.prototype.__super__ = A.prototype; B.prototype.method = function() { this.__super__.method.call(this); } function C() { B.call(this); } C.prototype = Object.create(B.prototype); C.prototype.__super__ = B.prototype; var b = new B(), c = new C(); b.method() // "works" c.method() // Maximum recursion depth exceeded 

Stack overflow because you did not receive the .__super__ you were expecting!

+3
source

All Articles