通过__proto__原型来继承JavaScript是否不好

Is it bad to inherit in JavaScript by putting __proto__ to prototype?

本文关键字:是否 JavaScript proto 原型 通过 继承      更新时间:2023-09-26

这是从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;,因为后者太啰嗦了。

通过放置 JavaScript 来继承 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 在 Web 浏览器的附加 ECMAScript 特性的(规范性(附录中包含了__proto__(注意,该规范编纂了已经实现中的内容(,但如果 ECMAScript 主机不是 Web 浏览器,则使其成为可选的。但是MDN说__proto__已被弃用。

另外,ES6引入了Object.setPrototypeOf(),它允许像__proto__一样更改原型,但MDN警告:

改变对象的[[Prototype]],使用此方法或 强烈建议不要弃用Object.prototype.__proto__, 因为它非常慢,并且不可避免地会减慢后续速度 在现代 JavaScript 实现中执行。