Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the JavaScript's Object.prototype behavior?

I ran into a strange snippet of code, which I cannot understand at all, here it is:

var obj = function() {};
obj.prototype.x = 5;

var instance1 = new obj();

obj.prototype = {y: 6};

var instance2 = new obj();

console.log(instance1.x, instance1.y, instance2.x, instance2.y);
// 5, undefined, undefined, 6

Now, the questions are:

  1. Why is this logging 5, undefined, undefined, 6 instead of undefined, 6, undefined, 6?
  2. Why replacing the prototype is not changing the prototype of all the instances of the object, as it would usually do?
  3. What is the V8 engine doing, step by step, in this code?
  4. EDIT: How would I go about changing the prototype of ALL the instances?

Every explanation is appreciated.

like image 337
Marco Bonelli Avatar asked Oct 12 '14 10:10

Marco Bonelli


People also ask

What is object __ proto __?

The __proto__ getter function exposes the value of the internal [[Prototype]] of an object. For objects created using an object literal, this value is Object. prototype . For objects created using array literals, this value is Array.

What is __ proto __ and prototype?

__proto__ is the actual object that is used in the lookup chain to resolve methods, etc. prototype is the object that is used to build __proto__ when you create an object with new : ( new Foo ).

What is the base prototype for all objects?

A prototype is just an object in memory. Every object has a prototype or parent except one object. We will refer to that object throughout the article as the base object. So Base Object doesn't have any prototype.

How do you get the prototype of an object?

getPrototypeOf() The Object. getPrototypeOf() method returns the prototype (i.e. the value of the internal [[Prototype]] property) of the specified object.


1 Answers

Explanation

So first, your two lines of code create a function, obj, and assign to it's prototype {x: 5}.

When you create an instance of this object, it seems to have an internal reference to the prototype that existed when it was new'd.

After this, you reassign the prototype to {y: 6} which does not affect the instance1 internal reference to the first prototype.

Then when you create instance2 it has an internal reference to the 2nd prototype and therefore, logging them will produce 5, undefined, undefined, 6.

#4

You could, rather than reassign the prototype to a new object:

obj.prototype = {y: 6};

Modify the prototype instead:

delete obj.prototype.x; // Setting to undefined should produce same behaviour
obj.prototype.y = 6;

This will produce the output: undefined, 6, undefined, 6

I have tested this with http://jsfiddle.net/9j3260gp/ on Chrome and Firefox latest versions on Windows.

like image 149
Winestone Avatar answered Sep 27 '22 02:09

Winestone