基本javascript继承问题

basic javascript inherits issue

本文关键字:问题 继承 javascript 基本      更新时间:2023-09-26

为了更好的结构,我尝试在Javascript中继承我的类。也许我的方法是完全错误的或不可行的。下面是我的示例代码:

function myMotherClass(value){
   this.MyValue = value
}
function myChildClass(value){
    this.prototype = new myMotherClass(value);
    this.alert = function(){
        alert(value);
    };
}
//myChildClass.prototype = new myMotherClass(1)
var myClass = new myChildClass(2);
myClass.alert();
这是我的小提琴!

正如您在我的小提琴中看到的,如果您使用注释行,它工作得很好。

如果你能看到小提琴,我试图给构造函数值在myChildClass的基础"myMotherClass"。但是正如您所看到的,有一个未定义的输出。

感谢您的时间和提前帮助。

它似乎与被注释掉的行一起工作的原因是,被注释掉的行中的myChildClass函数;但在myChildClass构造函数内的行中,this不是函数,而是new操作符创建的实例。函数的prototype属性是一个对象,它将被new操作符赋值给它创建的新实例,作为它们的底层原型;实例上的prototype属性没有特殊的含义(例如,它不引用实例的底层原型)。

正确的方法是:

// Parent constructor
function myMotherClass(value){
   this.MyValue = value
}
// Child constructor
function myChildClass(value){
    // Chain to parent constructor, passing any necessary args
    myMotherClass.call(this, value);
    // Other child stuff -- see note below
    this.alert = function(){
        alert(value);
    };
}
// Set up inheritance by creating myChildClass's prototype
// property to be an object that is baked by myMotherClass's
// prototype object; do NOT *call* myMotherClass here, it's
// a common anti-pattern you'll see in a lot of examples
inherit(myMotherClass, myChildClass);
// Create an instance    
var myClass = new myChildClass(2);
myClass.alert();

…其中inherit为:

function inherit(parent, child) {
    var temp;
    if (Object.create) {
        child.prototype = Object.create(parent.prototype);
    } else {
        temp = function() { };
        temp.prototype = parent.prototype;
        child.prototype = new temp();
    }
    child.prototype.constructor = child;
}

注意,通过定义alert的方式,会出现这种稍微奇怪的行为:

var o = new myChildClass(42);
console.log(o.MyValue); // 42
o.alert();              // alerts "42"
o.MyValue = 67;
console.log(o.MyValue); // 67
o.alert();              // alerts "42" <== !!!

你可以改变你对alert的定义,让它像这样使用MyValue:

this.alert = function() {
    alert(this.MyValue);
};

…前提是始终通过实例调用它。(更多关于我的博客:神话方法)

但是如果你要这样做,你可以把它移动到原型中——把它放在建立链的inherit调用之后:

myChildClass.prototype.alert = function(){
    alert(this.MyValue);
};

把它们放在一起:

// Parent constructor
function myMotherClass(value){
   this.MyValue = value
}
// Child constructor
function myChildClass(value){
    // Chain to parent constructor, passing any necessary args
    myMotherClass.call(this, value);
    // Other child stuff...
}
// Set up inheritance by creating myChildClass's prototype
// property to be an object that is baked by myMotherClass's
// prototype object; do NOT *call* myMotherClass here
inherit(myMotherClass, myChildClass);
// Add stuff to myChildClass's prototype property
myChildClass.prototype.alert = function(){
    alert(this.MyValue);
};
// Create an instance    
var myClass = new myChildClass(2);
myClass.alert();

如果您对JavaScript中的经典继承感兴趣,我有一个方便的辅助脚本Lineage,它使上述操作更简单,并添加了一些有用的功能:http://code.google.com/p/lineagejs/