Why is JavaScript prototype property undefined on new objects?

JavascriptPrototype

Javascript 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.

  1. [[prototype]] is a hidden property of a JavaScript object.This hidden property is nothing but a link to Object.prototype(If created by object literals).There is no standard way to access this [[prototype]] property.
  2. Functions in JavaScript are objects so they also have [[prototype]] property.Here, In case of function this hidden property is a link to Function.prototype.There is also no standard way to access this [[prototype]] property.
  3. Apart from this hidden link [[prototype]], Whenever a function object is created,a prototype 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 :

  1. If object O is created with O = new func(){} then O[[prototype]] is Function.prototype.

  2. If object O is created with O = {}then O[[prototype]] is Object.prototype.

  3. If object O is created with O = Object.create(obj) then O[[prototype]] is obj.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPascal ParadisView Question on Stackoverflow
Solution 1 - JavascriptPeter OlsonView Answer on Stackoverflow
Solution 2 - Javascriptthe systemView Answer on Stackoverflow
Solution 3 - JavascriptYuciView Answer on Stackoverflow
Solution 4 - JavascriptAnshulView Answer on Stackoverflow
Solution 5 - JavascriptDanilo ValenteView Answer on Stackoverflow