Why is JavaScript prototype property undefined on new objects?
JavascriptPrototypeJavascript Problem Overview
I'm fairly new to the concept of JavaScript's prototype concept.
Considering the following code :
var x = function func(){
}
x.prototype.log = function() {
console.log("1");
}
var b = new x();
As I understand it, b.log()
should return 1 since x
is its prototype. But why is the property b.prototype
undefined?
Isn't b.prototype
supposed to return the reference to the x
function?
Javascript Solutions
Solution 1 - Javascript
Only constructor functions have prototypes. Since x
is a constructor function, x
has a prototype.
b
is not a constructor function. Hence, it does not have a prototype.
If you want to get a reference to the function that constructed b
(in this case, x
), you can use
b.constructor
Solution 2 - Javascript
The .prototype
property of a function is just there to set up inheritance on the new object when the function is invoked as a constructor.
When the new object is created, it gets its internal [[Prototype]]
property set to the object that the function's .prototype
property points to.
The object itself doesn't get a .prototype
property. Its relationship to the object is completely internal.
That's why it works to do b.log()
. When the JS engine sees that the b
object itself has no log
property, it tries to look it up on the objects internal [[Prototype]]
object, where it successfully finds it.
To be clear, the [[Prototype]]
property is not directly accessible. It's an internal property that is only indirectly mutable via other constructs provided by the JS engine.
Solution 3 - Javascript
All ordinary objects in JavaScript have an internal prototype slot (note: the prototype here does not refer to the prototype property). The ECMAScript standard (http://www.ecma-international.org/ecma-262/6.0/index.html) specifies that this slot is referred to as [[Prototype]]. You could access this slot through the __proto__ property.
__proto__ may not be reliably available across browsers. __proto__ becomes an official property in ECMAScript 6
The prototype property is, however, a property on a constructor function that sets what will become the __proto__ property on the constructed object.
You can access the prototype property of certain types, e.g., the core JavaScript types (Date, Array, and etc). Also a JavaScript function (, which can be regarded as a constructor) has a public prototype property. However, instances of a function do not have a prototype property.
In you case, var b = new x();
, b is an instance of function x. Thus b.prototype is undefined. However, b does have an internal [[Prototype]] slot. If you output b.__proto__
in Google Chrome e.g., version 63.0.3239.132, or Firefox such as version 43.0.4
console.log(b.__proto__);
You will see its [[Prototype]] slot as below:
{log: ƒ, constructor: ƒ}
That's it.
And just for your reference, the whole code snippet is put as below:
var x = function() {
};
x.prototype.log = function() {
console.log("1");
}
var b = new x();
b.log(); // 1
console.log(b.prototype); // undefined
console.log(b.__proto__); // {log: ƒ, constructor: ƒ}
console.log(x.prototype); // {log: ƒ, constructor: ƒ}
Solution 4 - Javascript
Before going through your code I want to make sure some concept of prototype that are required to understand your code behavior.
[[prototype]]
is a hidden property of a JavaScript object.This hidden property is nothing but a link toObject.prototype
(If created by object literals).There is no standard way to access this[[prototype]]
property.- Functions in JavaScript are objects so they also have
[[prototype]]
property.Here, In case of function this hidden property is a link toFunction.prototype
.There is also no standard way to access this[[prototype]]
property. - Apart from this hidden link
[[prototype]]
, Whenever a function object is created,aprototype
property is created within it, which is separate from hidden[[prototype]]
property.
Now coming to your code :
> var x = function func(){}
When this line execute , a function object x
is created with two links :
- Function.prototype (not accessible),
- x.prototype (accessible).
> x.prototype.log = function() { console.log("1"); }
as we know now that x
is a function object so x.prototype
is accessible, so here you are able to include log method with it.
> var b = new x();
b
is an object but not function object .It has that hidden link [[prototype]]
but It is not accessible. so when you try to access like b.prototype
it gives undefined
as a result.If you want to check the prototype of b
than you can see (x.prototype).isPrototypeOf(b);
it will return true
. so you can say that hidden link is referenced to x.prototype
.
Here are some facts about prototype :
-
If object
O
is created withO = new func(){}
then O[[prototype]] isFunction.prototype
. -
If object
O
is created withO = {}
then O[[prototype]] isObject.prototype
. -
If object
O
is created withO = Object.create(obj)
then O[[prototype]] isobj
.
Solution 5 - Javascript
Because prototype
is a property of functions (actually, constructors), since it defines the properties/methods of objects of this class (those which were created from the constructor this prototype belongs). Take a look at this link