I am learning JS prototype, and I got the following code, all is clear except the output of console.log(myObj.name)
. How come it gives the name of the object itself, which is myObj
? Doesn't it need to find the prototype from its upper-level object?
const myObj = function () {}
myObj.prototype.name = 'prototype.name'
myObj1 = new myObj()
console.log(myObj.name) // => myObj
console.log(myObj1.name) // => 'prototype.name'
console.log(myObj.prototype.name) // => prototype.name
I was expecting the same output as myObj1
and their prototype.
CodePudding user response:
.prototype
is not the same as the prototype.
When you use the new
operator, the prototype of the object being created is set to the .prototype
attribute of the constructor function. So, when myObj1
is created, its prototype is myObj.prototype
and contains a .name
attribute. Now, myObj1
has .name
in its prototype chain, but myObj
doesn't; it has the attribute .prototype.name
. See this MDN article for more.
Look at this for an example:
const a = function() {}
a.prototype.greeting = "Hello";
const b = new a();
console.log(a.greeting);
console.log(b.greeting);
console.log(a.prototype.greeting);
However, the .name
attribute is special in your case. As Felix Kling pointed out in the comments of the question, myObj
is a function, and every function has a special .name
attribute that contains the name of the function (ie: 'myObj'
). So, you are being confused because myObj.name
is a completely separate thing from myObj.prototype.name
and myObj1.name
, which are the same.
CodePudding user response:
Doesn't it need to find the prototype from its upper-level object?
Assuming you know about prototypal inheritance and that in JS, object derives from another object (unlike class based inheritance), I think what you call upper-level
object is the prototype.
When a function is used as a constructor to create an object, in your case myObj1
, that object derives from the object referenced by the prototype
property of that function. Here myObj1
derives from myObj.prototype
. So, when you read a property myObj1.X
and that property does not exist, runtime will go up the derivation tree and look for myObj.prototype.X
.
However, myObj
itself is a function
(and also an object). All functions derive from built-in Function.prototype
. For example,
Function.prototype.myprop = 'somevalue'; //Note: not a good practice to modify Function.prototype, this is just for demo
let myObj = function() {} // myObj derives from Function.prototype
console.log(myObj.myprop); // => somevalue
In your case however, myObj.name
really actually refers to Function.prototype.name
, which is JS built-in property and is readonly.