JavaScript 继承和超级构造函数
I have found and adapted a JavaScript "class" extend function 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 out-commented code line).
I like the out-commented version more because:
You can access super properties via
this.__super__.propertyName
instead ofClassName.__super__.propertyName
. So you have no redundancy in the class naming.This makes even more sense for nested inheritance since you can use
this.__super__.__super__.propertyName
instead ofClassName.__super__.constructor.__super__.propertyName
I do not see any reason for it, but you could even still call "static" functions in a "static" way like that:
ClassName.prototype.__super__.constructor.staticMethod()
Are there any drawbacks with my version that I might have overlooked?
EDIT: I corrected the line to var hasProp = Object.prototype.hasOwnProperty;
Because you're not supposed to use __super__
in your code at all.
It's a compiler artifact, every use of the super
macro/keyword/whatever it is will compile to
ClassName.__super__.methodName.call(this, …) // or
ClassName.__super__.methodName.apply(this, …)
// or, in static class functions even
ClassName.__super___.constructor.functionName.call(this, …)
They don't trust the dynamic this
binding that you have proposed to use (this.__super__
), they rather went for a static reference of the parent. Actually it might have been a good idea not to use a property at all, but just a local super
variable in their module scope.
Also, this.__super__
will not work in an 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 get the .__super__
that you expected!
相关文章