基本javascript继承了这个问题

基本javascript继承了这个问题,javascript,inheritance,Javascript,Inheritance,为了获得更好的结构,我尝试在Javascript中继承我的类。也许我的方法完全错误或不可行。下面是我的示例代码: function myMotherClass(value){ this.MyValue = value } function myChildClass(value){ this.prototype = new myMotherClass(value); this.alert = function(){ alert(value); };

为了获得更好的结构,我尝试在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中的cunstructor值赋予基“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;
}
请注意,按照您定义
警报的方式,会出现这种稍微奇怪的行为:

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" <== !!!
…前提是您总是通过实例调用它。(更多关于我的博客:神秘的方法)

但如果要这样做,可以将其移动到原型中--将其放在设置链的
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中的经典继承感兴趣,我有一个方便的助手脚本,
沿袭
,这使上述内容更简单,并增加了一些有用的功能:

通常,OP发布的示例是通过使用
构造函数和
原型链来实现的。请参阅。有关几乎重复的讨论,请参阅。@sarbbottam:除了在那篇文章中,Crockford犯了一个典型的错误,即在创建子构造函数的原型时调用父构造函数,这是一个反模式,甚至不能正确地使用他的示例(
Parenizor
期望收到一个
参数,但
ZParenizor.inherits(Parenizor)
调用
Parenizor
而没有[inside
inherits
])。Hej,感谢您提供了这个大而详细的答案,我将尝试您的建议,并在尝试后将其标记为答案:-)@Ipad:不客气。顺便说一句,由于编辑错误,我在
inherit
中声明了一个从未使用过的变量,并在上面进行了清理。:-)
// 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();