Reputation: 15229
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 fromFunction.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
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 toFunction
and letFunction.prototype
be undefined? Functions would be derived fromFunction
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
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
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