JavaScript原型继承中,为什么不能在子类的构造函数中创建并保存父对象?

3
在这段JavaScript代码中,当实例化new child导致其构造函数执行时,create方法似乎没有创建父对象。子对象似乎没有继承父对象的成员函数m
function parent() {
    parent.prototype.a =2;
    parent.prototype.m = function() {
    return this.a++;
    }
}

function child() {
    child.prototype = Object.create(parent.prototype);
    child.prototype.constructor = parent;
    parent.call(this);
}

var c = new child();
alert(child.prototype.m());   // 2
alert(child.prototype.m());   // 3
alert(c.m());                 // FAILS!!!
3个回答

3
您的原型方法和继承应该在函数外定义...
function parent() {
}
parent.prototype.a =2;
parent.prototype.m = function() {
    return this.a++;
}

function child() {
    parent.call(this);
}
child.prototype = Object.create(parent.prototype);

var c = new child();
alert(child.prototype.m());   // 2
alert(child.prototype.m());   // 3
alert(c.m());                 // 4

2
以下是运行new child时的基本流程:
var obj = Object.create(child.prototype);
child.call(obj);
return obj;

内联你的构造函数将会像这样:

内联你的构造函数将会像这样:

var obj = Object.create(child.prototype);
// inline
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = parent;
parent.prototype.a =2;
parent.prototype.m = function() {
    return this.a++;
}
// end inline
return obj;

你是否注意到构造函数中没有任何修改obj的方式?虽然你修改了child.prototypeparent.prototype,但这对obj没有影响,因为你用child.prototype = Object.create(parent.prototype)创建了一个新对象,其中obj继承自旧的child.protoype对象。
以下是一个简化的示例:
var proto = {};
var obj = Object.create(proto);
proto = {};
proto.m = function() {};

很明显,给proto.m赋值不会影响obj,因为我们之前已经给proto赋了一个新对象o。
在Stack Overflow上已经有很多关于JS中OOP的问题,您可以轻松搜索它们。我还建议阅读MDN关于JS OOP的文章使用`Object.create`继承的好处

1

看起来您误解了如何在JavaScript中设置自定义对象。通常情况下,您应该将方法添加到构造函数之外的原型中,如果在内部添加,则每次调用构造函数时都会重置属性。

function parent() {
}
parent.prototype.a = 2;
parent.prototype.m = function() {
    return this.a++;
}

function child() {
    parent.call(this);
}
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = parent;

var c = new child();
alert(child.prototype.m());   // 2
alert(child.prototype.m());   // 3
alert(c.m());                 // 4

在这种情况下,它失败是因为您为子对象创建了新的原型。
Object.create(parent.prototype);

在父构造函数中设置 m 方法之前。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接