Tarun Maganti
Tarun Maganti

Reputation: 3076

How are Function objects different from Normal objects?

How are functions stored in a variable?

According to MDN

In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.

Suppose this scenario,

var fn = function () {};
fn.attr = 3;

console.log(fn); //prints function() {}

console.log(Object.keys(fn)); //prints ["attr"]

If a function is an object shouldn't it have keys and value kind where the function is stored in a property and the interpreters don't show that property? Something like C++ style operator overloading or array/object representation in Javascript itself. I mean to say are functions (or arrays) are just objects treated in a different manner? Which might imply that anonymous functions are stored in an object with a hidden property.


In summary, what is the underlying working of functions(or arrays)? Are they treated specially? Or are they just syntactic sugar for some hidden property which is called when () is used?

Upvotes: 4

Views: 122

Answers (1)

Ben Aston
Ben Aston

Reputation: 55729

Yes, functions are special.

Proof

const f = Object.create(Function.prototype);
f(); // TypeError: f is not a function

Exposition

They are "callable objects" that can only be created via prescribed syntax (function expressions, statements, declarations, fat-arrows, object literal method definition shorthand, Function constructor, class methods).

That means they have a special [[Call]] method (not visible to you) that is called when you invoke them with the () syntax.

[[Call]] coordinates:

  • the creation of the execution context (call-stack frame)
  • addition of the new execution context to the top of the stack
  • execution of the function logic
  • removal of the execution context from the stack
  • cueing up the next context to run (the one immediately lower on the stack)
  • supplying any return value to the next execution context

Creation of the execution context in turn completes configuration of the LexicalEnvironment (used for scoping), configuration of the receiver (this) for the function and other meta-logic.

Functions also differ from most normal objects in that they have Function.prototype on their [[Prototype]] chain (although you can create your own 'useless' object by inheriting from Function.prototype - see above).

For a full list of differences, please see MDN, the spec etc.

Upvotes: 5

Related Questions