扩展 Object.setPrototypeOf() 与 Object.create

Jes*_*sus 6 javascript

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

选项 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);
Run Code Online (Sandbox Code Playgroud)

选项 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);
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*n H 3

根据MDN 文档

根据现代 JavaScript 引擎优化属性访问的本质,更改对象的 [[Prototype]] 目前在每个浏览器和 JavaScript 引擎中都是非常缓慢的操作。此外,更改继承的影响是微妙且广泛的,并且不仅仅限于花费在 Object.setPrototypeOf(...) 语句中的时间,还可能扩展到有权访问其 [ 的任何对象的任何代码。 [原型]]已被更改。

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

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

简而言之,看起来使用速度比大规模使用时Object.create 要快得多Object.setPrototypeOf

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