user924731
user924731

Reputation: 195

Javascript object constructor - strange behaviour

I've been learning Javascript's prototype inheritance, and I've got the following in a tag in the body of a html page:

function F() {}
//F.prototype = {a:"hello"};
var x = new F();
document.write(x.constructor);

This results in the following printout in the browser:

function F() { }

However , if I uncomment the second line, the following results:

function Object() { [native code] }

Nevertheless, x is still inheriting from the F's prototype, since when I change the last line to the following...

document.write(x.a);

...I get the following printout:

hello

I've tried this in Firefox and Safari, and the same thing happens in both.

Does anyone have any idea what on earth is going on here?

Upvotes: 1

Views: 139

Answers (2)

Felix Kling
Felix Kling

Reputation: 816272

Each object has a constructor property in its prototype chain, since each object ultimately inherits from Object.prototype.

Since you set a plain object as prototype of F, x.constructor is now referring to the constructor property of that object, which refers to Object.prototype.constructor.

The prototype chain looks like this:

x -> F.prototype -> Object.prototype

and since neither x nor F.prototype have a constructor property, the value of Object.prototype.constructor is returned.

The value of F.prototype before you override it is something like:

F.prototype = {
    constructor: F;
};

i.e. it has a constructor property. That's why you should always set constructor properly if you override the prototype:

F.prototype = {a:"hello"};
F.prototype.constructor = F;

Upvotes: 1

user1106925
user1106925

Reputation:

It's because you've eliminated the default .constructor property when you replaced the original .prototype object.

So now, when you look for a .constructor property it continues down the prototype chain of the given .prototype object, until it finds one, which it'll get from the default Object.prototype.

When a .prototype object has been replaced, some people like to reassign the missing .constructor...

function F() {}
F.prototype = {a:"hello"};
F.prototype.constructor = F;

Upvotes: 0

Related Questions