1

https://danmartensen.svbtle.com/the-anatomy-of-a-javascript-function#creating-function-instances_3

I am trying to understand this article on how javascript function objects are created. It says:

The new instance object is implicitly assigned many internal properties, one being the [[prototype]] property. The Function constructor’s prototype property referencing it’s prototype object is copied into this new object’s [[prototype]] property

Basing on the above statement i wrote this code:

function Person(){

}

console.dir(Function.prototype);
console.dir(Person.prototype);

According to the statement Function.prototype is assigned to a newly created function object's prototpe (Person.prototype in this case). i printed both of them. Contents look different.

Can someone explain where my understanding went wrong. By the way i looked at Ecmascript specs as well, it has the same statement

enter image description here

lch
  • 4,569
  • 13
  • 42
  • 75
  • According to javascript functions are objects. Even Ecmascript calls the same http://www.ecma-international.org/ecma-262/5.1/#sec-13.2 – lch Sep 20 '16 at 18:50
  • I want to know how each function get its internal properties and methods like prototype, call, bind etc – lch Sep 20 '16 at 18:51

2 Answers2

5

According to the statement, Function.prototype is assigned to a newly created function object's prototype (Person.prototype in this case)

No. The text talks about internal properties, such as [[prototype]]. You cannot access it as a normal property, you can access it using Object.getPrototypeOf. And indeed,

Object.getPrototypeOf(Person) === Function.prototype // true

The .prototype property is a different thing. It does get created on instantiation of the function object as well, but it does get filled with an object that inherits from (has [[prototype]]) Object.prototype and contains a .constructor property pointing back to the function. This object will become the [[prototype]] of instances created using new Person.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • "You cannot access it as a normal property". But We add properties to prototype? to make those properties available to all instances of that function – lch Sep 20 '16 at 19:02
  • Yes, the properties *of* the object referenced by [[prototype]] can be accessed as normal, because they are inherited (which is what the whole thing is about), but the [[prototype]] link itself cannot be accessed using a property. – Bergi Sep 20 '16 at 19:04
2

You are experiencing the classic confusion between the prototype property, and an object's prototype. They are entirely different, although related.

The prototype property of a function is an object which is set as the prototype for objects created using that function as a constructor. Initially, it is an empty object except for a constructor property pointing back to the constructor.

The prototype (not the prototype property) of an object is set when the object is created, from the prototype property of the constructor. It may be referred to as the __proto__ property, or retrieved via Object.getPrototypeOf.

In your case, Person has a prototype property which is initially basically empty except for the constructor property. It has nothing to do with the prototype property of the Function object. It becomes the prototype of instances of Person created via new Person(). You can add your own methods and properties to it, as in Person.prototype.alert = function() { alert(this.name); };.

Entirely separately from its prototype property, Person has a prototype which comes from the prototype property of the Function object, since Person is implicitly created using the Function constructor. That's where Person gets bind etc. (although if you intend to use Person as a constructor, I doubt if you'd find much use for bind).

To get a better idea, try the following in your console:

function Person() { }
Person.__proto__ === Function.prototype  // true
Function.prototype.isPrototypeOf(Person) // true
Object.getPrototypeOf(Person) === Function.prototype // true