JavaScript继承和超级构造函数

时间:2014-07-11 13:45:51

标签: javascript inheritance coffeescript

我找到并改编了一个JavaScript" class"扩展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;
    };

})();

我想知道,如果他们使用child.__super__而不是child.prototype.__super__的原因(请参阅注释掉的代码行)。

我更喜欢评论时的版本,因为:

  1. 您可以通过this.__super__.propertyName而非ClassName.__super__.propertyName访问超级媒体资源。所以你在课程命名中没有冗余。

  2. 这对嵌套继承更有意义,因为您可以使用this.__super__.__super__.propertyName代替ClassName.__super__.constructor.__super__.propertyName

  3. 我认为没有任何理由,但你甚至可以打电话给#34;静电"功能在"静态"这样的方式:

    ClassName.prototype.__super__.constructor.staticMethod()
    

    我的版本是否有任何我可能忽略的缺点?

    编辑:我将该行更正为var hasProp = Object.prototype.hasOwnProperty;

1 个答案:

答案 0 :(得分:3)

因为您根本不应在代码中使用__super__

这是一个编译器工件,每次使用super macro/keyword/whatever it is都会编译为

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

他们不信任您建议使用的dynamic this bindingthis.__super__),他们宁愿选择父母的静态参考。实际上,最好不要使用属性,而只是在模块范围内使用本地super变量。


此外,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因为你没有得到你期望的.__super__