Reputation: 23858
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?
Upvotes: 0
Views: 115
Reputation: 105547
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
Upvotes: 4
Reputation: 7496
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
Upvotes: 1