Why Is FunctionName() == FunctionName.prototype.constructor()
Solution 1:
why and when a function's definition is implicitly set to its constructor
This is not what is happening. You misunderstand the purpose of a function's prototype
property.
Any function in JavaScript can be a constructor function. A "constructor function" is simply an ordinary function called with new
, e.g., new foo()
.
When a function is called with new
, the function returns a newly-created object whose prototype chain begins with the function's prototype
property. The object's __proto__
property (or [[Prototype]]
internal property, in ECMAScript terms) is set to the constructor function's prototype
property.
function Boat() { }
var titanic = new Boat();
console.log(titanic.__proto__ == Boat.prototype); // true
Since a function may be used as a constructor with new
at any time, every function must have a prototype
property for a constructed instance to use as the start of its prototype chain.
An instance's constructor
property is used to help that instance identify which constructor created it. To facilitate this, the instance has a constructor
property inherited from its prototype chain, which is set to start with the constructor function's prototype
property. Any time a function object is created, it is supplied with a prototype
property, and that prototype
property has a constructor
property set to the function itself.
function Boat() { }
var titanic = new Boat();
// what constructor function made this instance? The Boat function did
console.log(titanic.constructor == Boat);
// does titanic have its own `constructor` property? no, it does not
console.log(titanic.hasOwnProperty("constructor") == false);
// the `constructor` property is inherited from the prototype chain
console.log(titanic.__proto__.constructor == Boat);
// titanic's prototype chain begins with `Boat.prototype`
console.log(titanic.__proto__ == Boat.prototype);
// these are the same
console.log(titanic.__proto__.constructor == Boat.prototype.constructor);
// these are also the same
console.log(titanic.constructor == Boat.prototype.constructor);
This behavior is described in ES5 13.2, Creating Function Objects, steps 16 through 18:
- Create a new native ECMAScript object and let F be that object.
- Set all the internal methods, except for [[Get]], of F as described in 8.12.
- Set the [[Class]] internal property of F to "
Function
".- Set the [[Prototype]] internal property of F to the standard built-in Function prototype object as specified in 15.3.3.1.
...
- Let proto be the result of creating a new object as would be constructed by the expression
new Object()
whereObject
is the standard built-in constructor with that name.- Call the [[DefineOwnProperty]] internal method of proto with arguments "
constructor
", Property Descriptor {[[Value]]: F, ...} ...- Call the [[DefineOwnProperty]] internal method of F with arguments "
prototype
", Property Descriptor {[[Value]]: proto, ...} ...
Solution 2:
JavaScript ONLY has one construct - they are objects. Each object is linked to another object via its prototype. As you call a functions properties, JavaScript will look in the object's prototype, the father's object's prototype, ect until it finds the property you are looking for. The last line in the prototype searching is something like if you call toString(), it will search for this, and unless you have overridden the toString() property, then it will find toString() in Object.prototype.
When you declare a function, the interpreter creates a new function object and populates the prototype property. Note: the default value for the prototype is an object with a property constructor.
function functionName() {}
var newFunction = new functionName();
newFunction.hasOwnProperty('constructor') //false
newFunction.prototype.hasOwnProperty('constructor') //true as you noted above
Post a Comment for "Why Is FunctionName() == FunctionName.prototype.constructor()"