0

In JS functions are said to be objects. Now when functions are tested against objects, they behave differently.

a = {};
console.log(a.prototype); //undefined
function myFunc() {};
console.log(myFunc.prototype); //Object
Object.getPrototypeOf(myFunc); //function(){}

And to make things worst, an example in this MDN article seem to change the constructor of a function prototype.

secondConstructor.prototype.constructor = secondConstructor;

Can someone please explain this behaviour?

asked Nov 24, 2016 at 7:17
7
  • Hi, I cannot explain that behavior, but I can tell you to use typeof myFunc === "function" instead. on the other hand typeof {} === "object" Commented Nov 24, 2016 at 7:21
  • "Can someone please explain this behaviour?" What exactly are you trying to demonstrate to us? Plain objects don't have a .prototype property. That doesn't mean that functions aren't objects. Commented Nov 24, 2016 at 7:21
  • @JLRishe I'm not trying to demonstrate anything - but rather waiting for someone to demonstrate me how the above disparity in objects is possible in JS. Please look at the answer from Maximus for more info. Commented Nov 24, 2016 at 7:34
  • What disparity? You have to explain in your question in words. Just showing us a lump of code isn't enough. Commented Nov 24, 2016 at 7:36
  • @JLRishe Again see the answer from Maximus if you still don't understand my question. Commented Nov 24, 2016 at 7:39

2 Answers 2

4

What leads to a common confusion is that a function as an object has .__proto__ property and as a function has .prototype property. They have different meaning.

Most JavaScript objects have a prototype object, that can be accessed using Object.getPrototypeOf() method, or simply .__proto__ property. This is the object which is used to reuse code and is consulted when a property accessor can't find requested property on an object, then it's looked up on its prototype. This is how common methods like .apply are available on a function. This is how you access this object in your example:

Object.getPrototypeOf(myFunc); //function(){}

Only functions have .prototype property, which is used by new operator when a new object is created using the function. When a function is called with new operator and a new object is created, JS checks the .prototype property of the function. If it points to an object, JS sets this object as a prototype of a newly created object. That's why the .prototype of an object in your example is undefined:

a = {};
console.log(a.prototype); // undefined

Can someone please explain this behaviour?

secondConstructor.prototype.constructor = secondConstructor;

The constructor property of an object usually points at the function that was used to create the object. When a function is declared, this property is created automatically on the object that .prototype property of the function points to.

function c() {}
c.prototype.constructor === c; // true
var o = new c();
o.constructor === c; // true

However, this property can easily be changed:

c.prototype = {constructor: function notCAnymore() {}}
var o = new c();
o.constructor === c; // false

Now we don't have a reference to the correct function anymore. So after changing the prototype, we may need to restore the .constructor property:

c.prototype = {constructor: function notCAnymore() {}}
c.prototype.constructor = c; // restoring the correct constructor
var o = new c();
o.constructor === c; // true

And that is exactly what is done in the example. The prototype is changed:

secondConstructor.prototype = new firstConstructor;

If object is created now the pointer to a correct constructor is lost:

var o = new secondConstructor();
o.constructor === secondConstructor; // false

That's why they use this code to restore it:

secondConstructor.prototype.constructor = secondConstructor;
var o = new secondConstructor();
o.constructor === secondConstructor; // true
answered Nov 24, 2016 at 7:20
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. It explains the mystery. Also can you please cover some background about the MDN article setting the constructor in that manner?
Thank you very much. Very well explained.
@CharlieH, you're welcome. It's indeed a confusing topic.
1

For your first statement

var a = {};
console.log(typeof(a));
console.log(Object.getPrototypeOf(a));

Here a, is just an object ,when you check its type it just returns object and you cannot access its prototype

All JavaScript objects inherit the properties and methods from their prototype.

Objects created using an object literal, or with new Object(), inherit from a prototype called Object.prototype

Here in the first case, a is just object literal so its prototype is empty.

In the second case, myFunc is a definition which objects can be created through new ,but it is also an object,so thats the reason the prototype is object here

The Object.getPrototypeOf() method returns the prototype (i.e. the value of the internal [[Prototype]] property) of the specified object.

For MyFunc the prototype is function because it has been defined as function

function myFunc() {};
console.log(myFunc.prototype); //Object
console.log(Object.getPrototypeOf(myFunc));

In the third snippet,It is the case of inheritance

function parent(name){
this.name=name;
}
function child(childname){
this.childname=childname;
}
child.prototype=Object.create(parent.prototype);
console.log(parent.prototype);
console.log(parent.prototype.constructor);
console.log(child.prototype);
console.log(child.prototype.constructor);

When child is inherting parent,its prototype and constructor is parent,in order to change the constructor to be of the same MDN has mentioned it as

child.prototype.constructor=parent;

Hope it helps

answered Nov 24, 2016 at 7:35

1 Comment

//Here in the first case, a is just object literal so its prototype is empty. This is wrong. The correct way of explaining this is that you cannot access the prototype of most of JS objects through "prototype" property.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.