简体   繁体   English

JavaScript继承和超级构造函数

[英]JavaScript inheritance and super constructor

I have found and adapted a JavaScript "class" extend function from coffeescript: 我已经从coffeescript找到并改编了JavaScript“类”扩展功能:

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). 我想知道他们是否有理由使用child.__super__而不是child.prototype.__super__ (请参见注释掉的代码行)。

I like the out-commented version more because: 我更喜欢注释过的版本,因为:

  1. You can access super properties via this.__super__.propertyName instead of ClassName.__super__.propertyName . 您可以通过this.__super__.propertyName而不是ClassName.__super__.propertyName来访问超级ClassName.__super__.propertyName So you have no redundancy in the class naming. 因此,在类命名中没有多余的内容。

  2. This makes even more sense for nested inheritance since you can use this.__super__.__super__.propertyName instead of ClassName.__super__.constructor.__super__.propertyName 对于嵌套继承,这更有意义,因为可以使用this.__super__.__super__.propertyName代替ClassName.__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; 编辑:我将行更正为var hasProp = Object.prototype.hasOwnProperty;

Because you're not supposed to use __super__ in your code at all. 因为您根本不应该在代码中使用__super__

It's a compiler artifact, every use of the super macro/keyword/whatever it is will compile to 这是一个编译器工件,每次对super宏/关键字/进行任何使用都会编译为

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. 他们不信任您建议使用的动态this绑定this.__super__ ),而是去寻求父级的静态引用。 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. 实际上,最好根本不使用属性,而只在模块范围内使用局部super变量。


Also, this.__super__ will not work in an inherited method: 另外, this.__super__不能在继承的方法中工作:

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! 堆栈溢出,因为您没有获得预期的.__super__

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM