【问题标题】:Extends Object.setPrototypeOf() vs Object.create扩展 Object.setPrototypeOf() 与 Object.create
【发布时间】:2019-10-14 12:58:14
【问题描述】:

我知道继承函数构造函数的两种方法。

选项 1 Object.create

function x(x, y) {
  this.x = x;
  this.y = y;
}

x.prototype.XDD = function() {};


function y(c, r) {
  x.call(this, 1, 2);
  this.r = r;
  this.c = c;
}

y.prototype = Object.create(x.prototype);
y.prototype.YDD = function() {};
y.prototype.XDD = function() {};
y.prototype.constructor  = y;

var rect = new y(1, 2);

选项 2 Object.setPrototypeOf()

function x(x, y) {
  this.x = x;
  this.y = y;
}

x.prototype.XDD = function() {};

function y(c, r) {
  x.call(this, 1, 2);
  this.r = r;
  this.c = c;
}

y.prototype.YDD = function() {};
y.prototype.XDD = function() {};
Object.setPrototypeOf(y.prototype, x.prototype);

var rect = new y(1, 2);

它们之间有什么区别?。还有比这些更好的解决方案吗?。

【问题讨论】:

  • 回答最后一个问题,是的,有:class Foo extends Bar
  • Upto Preference -JS 基于prototypal inheritanceObject.create,仅此一个。但对class and object 更有经验的人更喜欢class 关键字
  • 尽管存在性能问题,但使用Object.setPrototypeOf() 也表明您可能希望在事件之后 更改原型。我想不出一个现实的例子来说明为什么你需要这样做,但是你去吧。

标签: javascript


【解决方案1】:

根据MDN docs

改变一个对象的 [[Prototype]] 现代 JavaScript 引擎优化属性访问,目前是一个非常 在每个浏览器和 JavaScript 引擎中运行缓慢。此外, 改变继承的影响是微妙而广泛的,并且是 不仅限于在 Object.setPrototypeOf(...) 中花费的时间 语句,但可以扩展到可以访问任何对象的任何代码 其 [[Prototype]] 已被更改。

因为这个特性是语言的一部分,它仍然是负担 让引擎开发人员高效地(理想情况下)实现该功能。 在引擎开发人员解决这个问题之前,如果您担心 性能,您应该避免设置对象的 [[Prototype]]。 相反,使用所需的 [[Prototype]] 创建一个新对象 Object.create()。

性能比较(2019 年 2 月 14 日): https://gist.github.com/calebmer/c74e2a7941044e5f28b8#gistcomment-2836415

简而言之,使用Object.create Object.setPrototypeOf非常更大规模使用时要快得多

还有许多其他方法可以在 JS 中设置对象的原型(例如不推荐使用 Object.prototype.__proto__),但现在(2019 年 10 月)最推荐的方法似乎是使用ES6 class, supported 被大多数现代浏览器所采用。虽然有基准(如:this)表明 ES6 类和super() 比 ES5 对应物慢,但它使您的代码更干净,尤其是对于使用其他 OOP 语言的人。

【讨论】:

  • 该基准的作用与 OPs 代码完全不同。
  • 没什么不同——它本质上显示了Object.createObject.setPrototypeOf之间的区别
  • 但是Object.create 调用与Object.setPrototype 调用的性能差异与 OP 代码无关。对它们只有一次调用,这是否需要 3ns 更长的时间都无关紧要。他只关心var rect = new y(1, 2);rect.YDD() 是否有区别。
  • 其实问题不在于创建对象或调用方法,而是问了两种继承方式:Object.create vs Object.setPrototypeOf。我同意你的观点,在大多数情况下你不会继承 10^8 次,但问题是明确地关于继承。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 2018-09-04
  • 2020-12-11
  • 2021-10-14
  • 2013-05-23
  • 2013-09-04
相关资源
最近更新 更多