【问题标题】:Javascript inheritance with access to *all* methods in 'superclass'?Javascript继承可以访问“超类”中的*所有*方法?
【发布时间】:2013-09-16 22:54:49
【问题描述】:

为了了解如何在 Javascript 中完成继承,我偶然发现了许多不同的实现,包括 Crockfords、Resigs、Prototypeklass 等。

我错过了(我为骚动做好准备)是 Smalltalkish 自我/超级对:self 扮演与 this 类似的角色,即代表当前“对象”,super 指的是超类-this 的唯一版本。

[Skip to "]" 如果你知道 super 在 Smalltalk 中的作用:假设 Subclass 已经覆盖了在 Superclass 中定义的 method1,我仍然可以在 Subclass.method2() 中使用 super.method1() 访问超类实现.这不会执行Subclass.method1() 代码。

function Superclass () {
}
Superclass.prototype.method1 = function () {
  return "super";
}

function Subclass () {
}
Subclass.prototype.method1 = function () {
  return "sub";
}
Subclass.prototype.method2 = function () {
  alert (super.method1 ());
}

var o = new Subclass;
o.method2 (); // prints "super"

]

那里有任何“Javatalk”包吗?到目前为止,我只看到了 Javascript 中的 OO 仿真,它可以访问当前定义的方法 (method2) 的超类实现,而不是任何其他 (例如 method1)。

谢谢,诺比

【问题讨论】:

    标签: javascript inheritance smalltalk super


    【解决方案1】:

    您在 JavaScript 中没有 super 功能。

    知道超类后,可以直接使用call调用超类方法:

    Superclass.method1.call(this);
    

    如果你想模拟一个通用的super(我不提倡),你可以使用这个:

    function sup(obj, name) {
         var superclass = Object.getPrototypeOf(Object.getPrototypeOf(obj));
         return superclass[name].apply(obj, [].slice.call(arguments,2));
    }
    

    你将用作

    sup(this, 'method1');
    

    代替你的

    super.method1();
    

    如果你有参数要传递:

    sup(this, 'method1', 'some', 'args');
    

    而不是

    super.method1('some', 'args');
    

    请注意,这假设您使用正确的原型继承

    Subclass.prototype = new Superclass();
    

    【讨论】:

    • 你的代替错了,更多的是代替super.method1.call(this);
    • @plalx 我的“代替”不是正确的 javascript,但请参阅 OP 的问题。
    • 只是他可能认为它们在逻辑上是等价的。
    • @dystroy 我会尝试你的方法和标记为答案的方法 - 标记另一个只是因为它在源代码中看起来更好 - 我认为sup(this, "method") 很难看。谢谢
    【解决方案2】:

    有很多方法可以在 JavaScript 中实现super 功能。例如:

    function SuperClass(someValue) {
        this.someValue = someValue;
    }
    
    SuperClass.prototype.method1 = function () {
        return this.someValue;
    };
    
    function SubClass(someValue) {
        //call the SuperClass constructor
        this.super.constructor.call(this, someValue);
    }
    
    //inherit from SuperClass
    SubClass.prototype = Object.create(SuperClass.prototype);
    
    //create the super member that points to the SuperClass prototype
    SubClass.prototype.super = SuperClass.prototype;
    
    SubClass.prototype.method2 = function () {
        alert(this.super.method1.call(this));
    };
    
    var sub = new SubClass('some value');
    
    sub.method2();
    

    编辑:

    这是一个非常通用的 super 方法示例,它依赖于非标准功能。 我真的不推荐这个,它只是作为学习目的。

    Object.prototype.super = function () {
        var superProto = Object.getPrototypeOf(Object.getPrototypeOf(this)),
            fnName = arguments.callee.caller.name,
            constructorName = this.constructor.name;
    
        if (superProto == null) throw constructorName + " doesn't have a superclass";
        if (typeof superProto[fnName] !== 'function') {
            throw constructorName + "'s superclass (" 
                + superProto.constructor.name + ") doesn't have a " + fnName + ' function';
        }
    
        return superProto[arguments.callee.caller.name].apply(
            this, 
            [].slice.call(arguments, 1)
        );
    };   
    
    
    function A() {
    }
    
    A.prototype.toString = function toString() {
        //call super method Object.prototype.toString
        return this.super();
    };
    
    var a = new A();
    
    console.log(a.toString());
    

    【讨论】:

    • Javascript 瘟疫之一 - “有很多方法” :-) 所以现在是编写我自己的子类化函数的时候了! SuperclassSubclassprototype 的重复次数如此之多——看起来一点也不干......无论如何,谢谢
    • @virtualnobi 你绝对可以制作这个 DRYer,特别是如果你将继承过程封装在一个函数中。你总是可以把它推到极致,并有一个非常通用的 super 方法,但我不推荐这个。
    【解决方案3】:

    好吧,长话短说:this 是我读过的最好的 JavaScript 教程。所以我可以向你推荐它。祝你好运!

    【讨论】:

    • 这绝对是值得的,我没有使用过引用许多不同语言的文章。我去看看
    • 我想,你会喜欢的 :) 祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 2013-10-09
    • 1970-01-01
    相关资源
    最近更新 更多