Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extends Object.setPrototypeOf() vs Object.create

Tags:

javascript

I know two ways to inherit function constructor.

Option 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);

Option 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);

What are the differences between them ?.And there is another solution better than these ?.

like image 547
Silicum Silium Avatar asked Oct 14 '19 12:10

Silicum Silium


1 Answers

According to MDN docs:

Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.

Because this feature is a part of the language, it is still the burden on engine developers to implement that feature performantly (ideally). Until engine developers address this issue, if you are concerned about performance, you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().

Performance comparsion (Feb 14 2019): https://gist.github.com/calebmer/c74e2a7941044e5f28b8#gistcomment-2836415

In short it looks like using Object.create is much faster then Object.setPrototypeOf when used at extremely larger scale.

There are many other ways to to set the prototype of an object in JS (like unrecommended use of Object.prototype.__proto__ ) but nowadays (Oct 2019) the most recommended way seems to be the use of ES6 class, supported by most modern browsers. While there are benchmarks (like: this) that indicates that ES6 classes and super() are slower than thier ES5 counterparts, it makes your code cleaner especially for people from other OOP languages.

like image 118
Beniamin H Avatar answered Nov 01 '22 09:11

Beniamin H