cadaniluk
cadaniluk

Reputation: 15229

Difference between Function and Function.prototype

According to this, functions inherit from Function and Function from Function.prototype in turn:

The global Function object has no methods or properties of its own, however, since it is a function itself it does inherit some methods and properties through the prototype chain from Function.prototype.

What's the point of Function.prototype then? Why not move its properties to Function and let Function.prototype be undefined? Functions would be derived from Function instead.

Same goes for Object etc.

Upvotes: 6

Views: 1789

Answers (3)

user663031
user663031

Reputation:

functions inherit from Function

You are quoting MDN loosely. What it actually says is:

function objects inherit from Function.prototype

Note that on the MDN page, the initial word "function" in the above sentence is capitalized, but only because it is at the beginning of the sentence, not because it is referring to the JS object Function. It is referring to regular old functions declared as function() { }.

Remember that MDN is written by mere mortals. I would prefer they did not use the words "inherit" and "inheritance", not to mention "derived". JS does not have the concept of inheritance in the strict sense of the word. If you use this terminology, you will end up confusing yourself. What JS has is prototypes associated with objects. When accessing a property on an object, if it is not found, the prototype is consulted. If not found there, since a prototype is also an object with a prototype, the prototype's prototype is consulted, and so on up the chain.

Therefore, the above sentence would better be written as "function objects have as their prototype Function.prototype".

The JS Function object is not directly associated with Function.prototype, other than the fact that Function.prototype is a property of Function, and, since the Function object is itself a function, it itself has Function.prototype as its prototype. Whatever properties may or may not be present on Function, or hung on it by you, have nothing to do with the prototype chain and are not "inherited" by anyone.

When you do (function() { }).call(), the call property/method is first looked up on the function object itself; if it does not exist there, as it normally would not, then it is looked up on the prototype assigned intrinsically when the function was declared, which is Function.prototype. Where else would you put methods such as call or apply if not on Function.prototype? What else would you call the prototype automatically assigned to functions other than Function.prototype?

As an aside, note that Function.call will resolve correctly to the internal call function. Why? Not because that is where call lives, or because that is from where regular functions "inherit" call, but rather because, since as I mentioned before, Function is itself a function, and therefore has the prototype Function.prototype, call can be found on its prototype chain.

What's the point of Function.prototype then? Why not move its properties to Function and let Function.prototype be undefined? Functions would be derived from Function instead.

X.prototype is a property on X used as the prototype for objects created using X as a constructor. Therefore, to assign the correct prototype to objects created using Function as a constructor (which includes functions declared as function x() { }), the prototype must be present as the prototype property on Function.

Upvotes: 7

Leah Zorychta
Leah Zorychta

Reputation: 13409

You need Function.prototype for if you want to extend functions, consider this:

Function.prototype.moo = 5;
function x() { };
console.log(x.moo); // 5

every function you make now has the property moo, versus:

Function.quack = 6;
function b() {};
console.log(b.quack); // undefined

This is not true if you just slap a property onto Function. Every function DOES NOT inherit properties assigned to Function, which is why you need Function.prototype.

Upvotes: 0

user5589903
user5589903

Reputation:

Functions on the prototype are only created once and shared between each instance. Functions created in the constructor are created as new objects for each new object created with the constructor.

As a general rule functions should be on the prototype since they will generally not be modified for different objects of the same type, and this has a slight memory/performance benefit. Other properties like objects and arrays should be defined in the constructor, unless you want to create a shared, static property, in which case you should use the prototype.

Its easier to see the distinctions with normal objects or arrays rather than functions

function Foo(){
  this.bar = [];
}
var fooObj1 = new Foo();
var fooObj2 = new Foo();

fooObj1.bar.push("x");
alert(fooObj2.bar) //[]
as opposed to:

function Foo(){
}

Foo.prototype.bar = []
var fooObj1 = new Foo();
var fooObj2 = new Foo();

fooObj1.bar.push("x");
alert(fooObj2.bar) //["x"]

Upvotes: 2

Related Questions