Reputation: 53
I cannot understand why the following code produces 'Smith' as output, and not 'Smith Foo'. Can you please clarify why it is happening? I cannot figure out how a childFoo
property lookup in the prototype chain finds a way to a prototype of child.
var parent = {};
var child = Object.create(parent);
Object.getPrototypeOf(parent).Surname = 'Smith';
var parentFoo = function parentFoo() {};
var childFoo = new parentFoo(); //Object.create(parentFoo);
Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';
console.log(childFoo.Surname);
// this outputs 'Smith' only.
Upvotes: 3
Views: 95
Reputation: 53
Here is the final answer:
function parentFoo() {};
var childFoo = new parentFoo(); //Object.create(parentFoo);
parentFoo.__proto__.Surname = 'Smith Foo';
console.log(childFoo.Surname);
console.log(parentFoo.__proto__);
parentFoo.__proto__.__proto__.Surname = 'Smith Foo';
console.log(childFoo.Surname);
console.log(parentFoo.__proto__.__proto__);
Here is what I found:
When using directly constructor function and 'new' keyword, your new object's immediate prototype will be special function prototype
When using directly constructor function and 'new' keyword, your new object's immediate prototype will be special function prototype
I hope I got it right this time :) Thank you all for helping out!
Upvotes: 0
Reputation: 36630
You did change the prototype of the Object object from which every object inherits (unless explicitly specified) with this line of code:
Object.getPrototypeOf(parent).Surname = 'Smith';
Here we can see the devtools which shows that you to a property Surname with the value of Smith on the Object prototype.
Then with the following line of code :
Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';
You put the string 'Smith Foo' as a surname property on the function prototype. Here is how this looks in the chrome devtools:
Here is what you should do to get your desired result:
var parent = {};
var child = Object.create(parent);
Object.getPrototypeOf(parent).Surname = 'Smith';
var parentFoo = function parentFoo() {};
var childFoo = new parentFoo(); //Object.create(parentFoo);
// change parentFoo to childFoo
Object.getPrototypeOf(childFoo).Surname = 'Smith Foo';
console.log(childFoo.Surname);
Upvotes: 0
Reputation: 11824
The source of the confusion here, I think, is the difference between getPrototypeOf(a)
and a.prototype
.
a.prototype
is the prototype that will be used to create instances of a
, like in new a()
.Object.getPrototypeOf(a)
returns the prototype that was used to create a
, like in a = new AClass()
.So, when you do a = new AClass()
, Object.getPrototypeOf(a)
is equal to AClass.prototype
, the prototype that was used to create a
.
Object.getPrototypeOf(parent).Surname = 'Smith';
Here, getPrototypeOf
returns the prototype used to create {}
, which is Object.prototype
. This line is equivalent to Object.prototype.Surname = 'Smith'
.
Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';
Here, getPrototypeOf
returns the prototype used to create parentFoo
, which is a function(){}
: The return value is Function.prototype
. This line is equivalent to Function.prototype.Surname = 'Smith Foo'
.
console.log(childFoo.Surname);
childFoo
is an instance of parentFoo
, but parentFoo.prototype
was not modified, so it is an empty object (except for builtins). Thus, childFoo.Surname
goes up the prototype chain, ending up at Object.prototype
—the root that all JS objects inherit from. That's where it finds the Surname
property that you defined earlier, 'Smith'
.
And if you do (function () {}).Surname
, you'll see the 'Smith Foo'
string, because it was defined on Function.prototype
.
(This can be a really tricky part of JS to wrap your head around, so I hope that made sense!)
Upvotes: 3