这是从 Parent
继承 Child
的一种方法:
function Parent(a)
{
this.a = a;
}
Parent.prototype =
{
constructor: Parent,
parentValue: 123
};
function Child(a, b)
{
Parent.call(this, a);
this.b = b;
}
Child.prototype =
{
constructor: Child,
childValue: 456,
__proto__: Parent.prototype
};
child = new Child(1, 2);
// Logs 1 2 456 123
console.log(child.a, child.b, child.childValue, child.parentValue);
这种继承方式有没有弊端?
这背后的基本原理是我想批量添加属性,例如Foo.prototype = { a: 1, b: 2 }
而不是 Foo.prototype.a = 1; Foo.prototype.b = 2;
,因为后者太冗长了。
最佳答案
Is it bad to inherit in JavaScript by putting
__proto__
?
是的,因为它不是标准 (*)。最好使用 Object.create
:
function Parent(a) {
this.a = a;
}
Parent.prototype.parentValue = 123;
function Child(a, b) {
Parent.call(this, a);
this.b = b;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.prototype.childValue = 456;
var child = new Child(1, 2);
console.log(child.a, child.b, child.childValue, child.parentValue);
// Logs 1 2 456 123
或者,如果您想支持旧版浏览器,您可以使用 Object.create
Child.prototype = new Parent();
请注意,此方法将导致 Child
实例继承未定义的 a
属性,但由于您将使用 Parent.call(this, a )
,这并不重要。
如果你想避免冗长的Foo.prototype.a = 1; Foo.prototype.b = 2;
,你可以使用extend
函数:
function extend(obj, props) {
for(var i in props) if(props.hasOwnProperty(i))
obj[i] = props[i];
}
extend(Child.prototype, {
constructor: Child,
childValue: 456
});
(*) ES6 在(规范性)附件中包含 __proto__
用于 Web 浏览器的附加 ECMAScript 功能(请注意,该规范对实现中已有的内容进行了编纂),但如果 ECMAScript 宿主,则将其设为可选不是网络浏览器。
但是 MDN 表示 __proto__
已被弃用。
或者,ES6 引入了 Object.setPrototypeOf()
,它允许像 __proto__
一样改变原型(prototype),但是 MDN 警告:
Mutating the
[[Prototype]]
of an object, using either this method or the deprecatedObject.prototype.__proto__
, is strongly discouraged, because it is very slow and unavoidably slows down subsequent execution in modern JavaScript implementations.
关于javascript - 通过将 __proto__ 放入原型(prototype)来在 JavaScript 中继承是不是很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23186057/