0

If I am not mistaken, using Object.setPrototypeOf() and __proto__ to change object prototype is considered deprecated as a "very slow operation". Also, IIRC, this can degrade the performance of objects in V8.

Also, it is usually not recommended to add properties to an object after creation as it can degrade the performance of objects in V8 as well (if I understand correctly explanations like this).

So, if I need to create an object with defined prototype AND properties, I have two options:

  1. Object.create() with both prototype and property descriptors arguments set. This is rather cumbersome way.

  2. Object literal with __proto__ and properties.

So the questions: are these two options equal with regard to performance? Or is the second way is just syntactical sugar for the same postponed Object.setPrototypeOf() operation internally? Has the second way any drawbacks? Are these drawbacks implementation-dependent or common (spec-dependent?)?

UPD

See also discussions in cross-posts:

https://github.com/nodejs/help/issues/2901

https://twitter.com/vsemozhetbyt/status/1292057058213269504

A naive benchmark: https://github.com/nodejs/help/issues/2901#issuecomment-671027781

vsemozhebuty
  • 12,992
  • 1
  • 26
  • 26

2 Answers2

1

No, __proto__ is deprecated because it should not be part of the language (but stays for backcompat).

On the other hand, setPrototypeOf is not deprecated but merely despised because of its performance impact. However, it's not much of a problem to call it on fresh objects, there's nothing to deoptimise yet and the object usages will be optimised with regard to the new prototype.

However, there's a much simpler way: combine Object.create with Object.assign:

Object.setPrototypeOf({…}, proto)

Object.assign(Object.create(proto), {…})
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

"__proto__ is slow" is the wrong information. Internally when you create an object, it has [[Prototype]] property which is set to its prototype.

function Product(price,title){

  this.Price = price; 
  this.Title  = title; 

}

 Product.prototype.owner = "foo";

 let p1 = new Product(10, "pen");

 p1.__proto__ === Product.prototype; // true 

So if you want to create an object from another object literal, you have only two choices either use Object.create or manually set __proto__.

Another option is to use constructors, as I showed above

vsemozhebuty
  • 12,992
  • 1
  • 26
  • 26
debugmode
  • 936
  • 7
  • 13