Skip to content Skip to sidebar Skip to footer

Why Is FunctionName() == FunctionName.prototype.constructor()

I noticed if I have the following: var functionName = function(){console.log('this is a function!')} calling functionName is equivalent to functionName.prototype.constructor becau

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:

  1. Create a new native ECMAScript object and let F be that object.
  2. Set all the internal methods, except for [[Get]], of F as described in 8.12.
  3. Set the [[Class]] internal property of F to "Function".
  4. Set the [[Prototype]] internal property of F to the standard built-in Function prototype object as specified in 15.3.3.1.

...

  1. Let proto be the result of creating a new object as would be constructed by the expression new Object() where Object is the standard built-in constructor with that name.
  2. Call the [[DefineOwnProperty]] internal method of proto with arguments "constructor", Property Descriptor {[[Value]]: F, ...} ...
  3. 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()"