JavaScript继承与超级构造函数

JavaScript继承与超级构造函数,javascript,inheritance,coffeescript,Javascript,Inheritance,Coffeescript,我发现并改编了coffeescript中的JavaScript“class”扩展函数: var extend = (function() { var hasProp = Object.prototype.hasOwnProperty; function ctor(child) { this.constructor = child; } return function(child, parent) { for (var key

我发现并改编了coffeescript中的JavaScript“class”扩展函数:

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.\uuuuusuper\uuuuuuuuuu
而不是
child.prototype.\uuuuuuusuper\uuuuuuu
(参见注释代码行)是否有原因

我更喜欢注释过的版本,因为:

  • 您可以通过
    this.\uuuuuuuuuuuuuuuuuuuuuuuuu.propertyName
    而不是
    ClassName.\uuuuuuuuuuuuuu.propertyName
    访问超级属性。因此,在类命名中没有冗余

  • 这对于嵌套继承更有意义,因为您可以使用
    This.\uuuuu super\uuuuuuu.propertyName
    而不是
    ClassName.\uuuuuu super\uuuuuuuu.propertyName

  • 我看不出有什么原因,但您甚至可以像这样以“静态”的方式调用“静态”函数:

    ClassName.prototype.__super__.constructor.staticMethod()
    
    我的版本有没有可能忽略的缺点


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

    因为您根本不应该在代码中使用
    \uuuu super\uuuu

    这是一个编译器工件,每次使用都会编译为

    ClassName.__super__.methodName.call(this, …) // or
    ClassName.__super__.methodName.apply(this, …)
    // or, in static class functions even
    ClassName.__super___.constructor.functionName.call(this, …)
    
    他们不信任您建议使用的(
    this.\uuuuu super\uuuuu
    ),他们更倾向于静态引用父对象。实际上,一点也不使用属性可能是个好主意,而只是在其模块范围内使用一个局部
    super
    变量


    另外,
    this.\uuu super\uuu
    在继承的方法中不起作用:

    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
    

    堆栈溢出,因为您没有获得预期的
    。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    因为你根本不应该在你的代码中使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    这是一个编译器工件,每次使用都会编译为

    ClassName.__super__.methodName.call(this, …) // or
    ClassName.__super__.methodName.apply(this, …)
    // or, in static class functions even
    ClassName.__super___.constructor.functionName.call(this, …)
    
    他们不信任您建议使用的(
    this.\uuuuu super\uuuuu
    ),他们更倾向于静态引用父对象。实际上,一点也不使用属性可能是个好主意,而只是在其模块范围内使用一个局部
    super
    变量


    另外,
    this.\uuu super\uuu
    在继承的方法中不起作用:

    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
    

    堆栈溢出,因为您没有获得预期的
    。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    因为你根本不应该在你的代码中使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    这是一个编译器工件,每次使用都会编译为

    ClassName.__super__.methodName.call(this, …) // or
    ClassName.__super__.methodName.apply(this, …)
    // or, in static class functions even
    ClassName.__super___.constructor.functionName.call(this, …)
    
    他们不信任您建议使用的(
    this.\uuuuu super\uuuuu
    ),他们更倾向于静态引用父对象。实际上,一点也不使用属性可能是个好主意,而只是在其模块范围内使用一个局部
    super
    变量


    另外,
    this.\uuu super\uuu
    在继承的方法中不起作用:

    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
    

    堆栈溢出,因为您没有获得预期的
    。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    因为你根本不应该在你的代码中使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    这是一个编译器工件,每次使用都会编译为

    ClassName.__super__.methodName.call(this, …) // or
    ClassName.__super__.methodName.apply(this, …)
    // or, in static class functions even
    ClassName.__super___.constructor.functionName.call(this, …)
    
    他们不信任您建议使用的(
    this.\uuuuu super\uuuuu
    ),他们更倾向于静态引用父对象。实际上,一点也不使用属性可能是个好主意,而只是在其模块范围内使用一个局部
    super
    变量


    另外,
    this.\uuu super\uuu
    在继承的方法中不起作用:

    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
    

    堆栈溢出,因为您没有获得预期的
    。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    你在哪里找到的?这是CoffeeScript生成的代码吗?是的,没错,但我稍微修改了一下。你在哪里找到这个?这是CoffeeScript生成的代码吗?是的,没错,但我稍微修改了一下。你在哪里找到这个?这是CoffeeScript生成的代码吗?是的,没错,但我稍微修改了一下。你在哪里找到这个?是CoffeeScript生成的代码吗?是的,没错,但我稍微修改了一下。好的,我看到我得到了相同的错误//最大递归深度超过了edok,我看到我得到了相同的错误//最大递归深度超过了edok,我看到我得到了相同的错误//最大递归深度超过了edok,我发现我得到了相同的错误//超过了最大递归深度