【问题标题】:Inheritance in Javascript - protoyping not in definition-part?Javascript中的继承-原型不在定义部分?
【发布时间】:2009-07-30 09:08:24
【问题描述】:

我目前正在从 AS3 切换到 JavaScript。
我在理解继承概念方面仍然存在一些问题。
我不明白为什么以下代码无法正常工作:

Base = function () {
    this.coolVar = "great";
}  

SmallControl = function () {

    // Inheritance:
    this.prototype = new Base();
    this.prototype.constructor = SmallControl;

    this.prototype.init = function(aMap) {
        console.log('init');
        console.log('coolVar?: ' + this.coolVar);
    }
}  
var foo = new SmallControl();  
//foo.init();         // --> TypeError: foo.init is not a function  
foo.prototype.init(); // --> works

如果我将原型定义放在“SmallControl”-Function 之外,一切正常……但我不明白。

【问题讨论】:

  • 乍一看,在我看来,当您定义时: this.prototype.init 您在原型对象而不是 SmallControl 对象上定义了 init,因为“this”与 SmallControl 不同 - 它是在运行时实例化 SmallControl 时的“当前对象”。这就是 foo.prototype.init 起作用的原因。当你说“将原型定义放在外面......”时,我假设你做了: SmallControl.prototype = function init(aMap) - 是的,这将起作用,并且是进行经典继承时的习语。示例:github.com/roblevintennis/Testing-and-Debugging-JavaScript/tree/…

标签: javascript class inheritance prototype


【解决方案1】:

我想你想要这样的东西:

// Create the super class
Base = function () {
    this.coolVar = "great";
};  

// Create the new class
SmallControl = function () {
}; 
// Set the prototype of SmallControl to be an instance of Base. 
// This runs the Base constructor _immediately_ which sets up the variable
SmallControl.prototype = new Base();
// Add the init method to the SmallControl class
SmallControl.prototype.init = function(aMap) {
    console.log('init');
    console.log('coolVar?: ' + this.coolVar);
}
// Create an instance of SmallControl    
var foo = new SmallControl();  
foo.init(); 

【讨论】:

  • -- David -- 不错的经典继承示例!罗马,这将工作。但是,如果您需要更高的效率,您将需要研究:“构造函数窃取”。然后你会想要替换 SmallControl.prototype = new Base();行,因为您将调用超级的构造函数两次。然后你需要实现一个辅助方法来继承cProto(Sub, Sup)。我有所有这些代码工作和 TDD 在这里:github.com/roblevintennis/Testing-and-Debugging-JavaScript
【解决方案2】:

prototype 只是构造函数的一个有意义的属性。对象的实际原型(在某些环境中可以作为属性__proto__ 访问,但这不是可移植的)在构造对象时设置为构造函数的prototype 属性。对构造函数原型的更改(向原型添加属性)将反映在活动对象中,但如果您将 Constructor.prototype 设置为完全不同的对象,则不会。

在您的构造函数中,您正在设置构造对象的prototype 属性 (this)。这个属性对于不是构造函数的东西没有特殊意义。当你在函数之外设置它时,你在构造函数上设置它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-28
    • 2010-09-28
    • 2010-09-28
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多