Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will the object change its hidden class if we create new prototype properties?

In V8, an object changes its hidden class when a new property is added.

function Point(x, y) {
  this.x = x; // This will create new hidden class
  this.y = y; // This too
}

My question is simple, will this create a new hidden class?

Point.prototype.z = null;

I ask this question because in a coding style guideline I have read, they said we should declare class properties by creating a prototype instead of assigning them in the constructor. This will also help us to easily document them with JSDoc.

Thanks a lot.

like image 301
Tony Dinh Avatar asked Aug 04 '14 02:08

Tony Dinh


People also ask

Which of the following has the special hidden property proto proto [[ prototype ]] prototype?

[[Prototype]] In JavaScript, objects have a special hidden property [[Prototype]] (as named in the specification), that is either null or references another object. That object is called “a prototype”: When we read a property from object , and it's missing, JavaScript automatically takes it from the prototype.

Do objects have prototype property?

Conceptually, all objects have a prototype (NOT A PROTOTYPE PROPERTY). Internally, JavaScript names an object's prototype as [[Prototype]]. There are two approaches to get any object (including non-function object)'s [[prototype]]: the Object. getPrototypeOf() method and the __proto__ property.

Which prototype property is a prototype object that is used to implement inheritance and shared properties?

Every object with its methods and properties contains an internal and hidden property known as [[Prototype]]. The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object.

What is the difference between __ proto __ and prototype?

prototype is a property of a Function object. It is the prototype of objects constructed by that function. __proto__ is an internal property of an object, pointing to its prototype.


1 Answers

The answer is yes: a new hidden class will be created. However it's important to understand that it will be the prototype object itself that will change its hidden class, not an object created by the Point constructor.

Any object has a hidden class attached to it. Lets look at the code

var o = new Point();
o.z = 0;  // (1)
Point.prototype.zz = 0;  // (2)

At any given moment any object has a hidden class, that means o, o.__proto__, o.__proto__.__proto__ have a distinctive hidden class associated with them.

When you add a new property to the object, it's only hidden class of that object that changes. If you change hidden class of the prototype, the hidden classes of objects that share that prototype do not change. There is no need for such a change because we don't expect hidden class of an object X to fully describe the layout of any object in its whole prototype chain, its hidden class describes layout of X and X alone. Furthermore it's simply infeasible to implement such downwards propagation: that would require VM to maintain backward links between prototypes and all associated objects: to be able at any moment for an object X to enumerate all objects Y that have Y.__proto__ === X.

For the code above that means that statement (1) changes only the hidden class of o and statement (2) changes only the hidden class of Point.prototype (which is the same object as o.__proto__) but not of o itself.

Furthermore if you consider the code like this:

Point.prototype.z = 0;  // Initial value
var o1 = new Point();
o1.z = 11;  // (3)
var o2 = new Point();

which is sometimes recommended then this is a performance antipattern precisely because hidden classes of o1 / o2 and Point.prototype are disconnected. Assignment at (3) would change the hidden class of o1 even though o1.__proto__ already has property z. Objects o1 and o2 will end up having different hidden classes which will cause all the code that uses both of them to go polymorphic and penalize the performance. Furthermore o1 will end up using more space than in case if z was added right in the constructor because z would be stored in the out-of-object property storage.

like image 197
Vyacheslav Egorov Avatar answered Nov 10 '22 05:11

Vyacheslav Egorov