以下是从Child
继承Parent
的一种方式:
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;
,因为后者过于冗长。
答案 0 :(得分:2)
通过放置
来继承JavaScript是不是很糟糕__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__
,但MDN警告:
使用此方法或更改对象的
[[Prototype]]
强烈建议不要使用已弃用的Object.prototype.__proto__
, 因为它很慢并且随后不可避免地减慢速度 在现代JavaScript实现中执行。