Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript object lost constructor when the prototype was changed

In below code

var A = function() {};
var a = new A();
var b = new A();

A.prototype = {};

var c = new A();
console.log(a.constructor === b.constructor);
console.log(a.constructor === c.constructor);

output is true and false.

I am interested in the false output. a and c were created using same constructor function which is A - why is their constructor property different? It seems I miss something.

PS. If I remove the line where I am changing prototype of A output is: true true.

like image 643
Giorgi Moniava Avatar asked Mar 11 '23 11:03

Giorgi Moniava


2 Answers

When you construct an object, the constructor's prototype property is copied to the new object's __proto__, so while a and b retain the old prototype (which also contains the .constructor property), c uses the new blank prototype (which doesn't have constructor as own property). Here's a diagram:

After a = new A; b = new A:

enter image description here

After A.prototype = {}; c = new A()

enter image description here

As you can see, direct assignment to a prototype breaks the JS object system and may lead to surprising results (which your very question demonstrates). That's why it's generally frowned upon.

like image 62
georg Avatar answered Mar 13 '23 01:03

georg


The problem is that when you use A.prototype={} it is changed the behavior of A object.

When you use A.prototype={}, A object lost it’s constructor.

Why it is this behavior ?

The constructor property is assigned to prototype function.

And in your case ,A.prototype is replaced with a new Object {}, which doesn't have constructor property as own property (but its prototype has and is equal to Object).

Lets see the following example:

function A() { } // (1)
A.prototype = {}  // (2)

Before (2)

Object.prototype
{
    constructor:Object
}

A.prototype
//was autocreated with A
{
    constructor:A
}

After (2)

Object.prototype
{
    constructor:Object
}

A.prototype
//reassigned with {}
{
   //no constructor
}
like image 40
Mihai Alexandru-Ionut Avatar answered Mar 12 '23 23:03

Mihai Alexandru-Ionut