10

I am trying to understand the JavaScript prototype and I am bit confused.There are tons of tutorials out there and each has different explanation on it. So I don't know where to start with.

So far I have created a simple JavaScript object

var a = {flag : 1}

In MDN, I read that

All objects in JavaScript are descended from Object

But I couldn't find the prototype for this object a a.prototype gives me undefined

Then I found the prototype is available in a.constructor.prototype. When I create a function var myfunc = function() {} and then myfunc.prototype is available. So the prototype property is directly available on functions and not on objects.

Please help me to understand this and what is that a.constructor.

Any help is greatly appreciated.

Vishnu Sureshkumar
  • 2,246
  • 6
  • 35
  • 52
  • This exact question was asked and answered about a week ago. I will attempt to find the duplicate. – jfriend00 May 07 '15 at 06:06
  • var a = {}; is the shorthand for new Object(). Which you know is the root of all objects – Haagenti May 07 '15 at 06:07
  • Another duplicate explanation: [Extending prototype on object literal](http://stackoverflow.com/questions/29977892/extending-prototype-on-object-literal/29977926#29977926) – jfriend00 May 07 '15 at 06:12

2 Answers2

5

Every function can be called as a constructor (with new keyword).

function Dog() {
  this.legs = 4;
}

When you call it as a normal function, var dog = Dog(), it will define window.legs in browsers to be 4 (something a bit different but related if in Node.JS), and set dog to undefined.

However, if you call it as a constructor, as var dog = new Dog(), it will make a new object, and set its constructor to this function, and assign this new object to dog. It will set its internal prototype (which can be accessed in some browsers as dog.__proto__) to the constructor's prototype (Dog.prototype). Or, in pseudocode,

var dog = {
  legs: 4
};
dog.constructor = Dog;
dog.__proto__ = Dog.prototype; // same as dog.constructor.prototype

Thus, dog.constructor.prototype is not, strictly speaking, the prototype of dog, it is the object that will get assigned to the prototype when the constructor function is run. And in particular, Dog.prototype is not prototype of the Dog function (just the prototype that its instances will acquire). The reason prototype is not available on non-functions is because non-functions can't be used as constructors, so it makes no sense to have it (since its only function is to be copied to constructed instance objects' __proto__).

The object in your example still has a prototype, but not directly accessible; you can either go the hacky route in the browsers that allow it (a.__proto__), or ask the browser nicely (Object.getPrototypeOf(a)).

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • Thanks for this great answer. You have mentioned in pseudocode dog.__proto__ = Dog.constructor.prototype; But dog.__proto__ == Dog.constructor.prototype is showing 'false' Could you please explain.? – Vishnu Sureshkumar May 07 '15 at 07:02
  • Typo, sorry. Should be `dog.constructor.prototype` (which is same as `Dog.prototype`). Edited. – Amadan May 07 '15 at 07:05
  • Could you please explain this line "And in particular, Dog.prototype is not prototype of the Dog function (just the prototype that its instances will acquire)" – Vishnu Sureshkumar May 07 '15 at 07:22
  • `Dog.prototype` is prototype of `dog` (i.e. of `new Dog()`), not of `Dog` (but we will colloquially say that `Dog.prototype` is a Dog prototype). `dog.__proto__` is also prototype of `dog` (as `dog.__proto__` and `Dog.prototype` are the same thing). Meanwhile, `Dog.__proto__` (which is equal to `Object.prototype`, in this case) is the prototype of `Dog` itself. Does that make sense? – Amadan May 07 '15 at 07:25
  • So Dog.prototype is not the prototype of Dog, but the prototype of its instance and Dog.__proto__ is the prototype of Dog, is that correct? – Vishnu Sureshkumar May 07 '15 at 07:33
  • And in our case Dog.__proto__ is function Empty() {} – Vishnu Sureshkumar May 07 '15 at 07:35
  • Yes, exactly so. `Dog.prototype` is the prototype of Dog objects (created by `new Dog()`). Prototype of `Dog`, `Dog.__proto__`, is `Function.prototype`, the prototype for all things created as functions. – Amadan May 07 '15 at 07:54
3

You can use Object.getPrototypeOf() instead to return you the prototype of Object.

To see this in your browser devtools, run the following:

var a = {flag: 1};
console.dir(Object.getPrototypeOf(a));
GregL
  • 37,147
  • 8
  • 62
  • 67