3

Where is Function in the prototype chain of a JavaScript function?

Working Example: In Chrome's console, I created the following function:

> var f = function() { alert(1); }

invocation with f() correctly results an an alert of the number 1. Upon examination of the function with the following console statement:

> console.dir(f)

Notice how the prototype is listed as Object, in the form of key/value pair prototype: Object, meaning that function f inherits directly from Object. Fair enough; arrays and other entities in JavaScript also inherit from Object.

The conflict results from the following observation. Enter the following command:

f instanceof Function

This results in true.

As I understand it, user-created functions inherit from the Function object, which in turn inherits from Object; however, for the life of me, I can't find it by inspecting the prototype chain for f.

Where is Function in the prototype chain for function f?

tyvm

kmiklas
  • 13,085
  • 22
  • 67
  • 103

3 Answers3

1

Where is Function in the prototype chain for function f?

Function itself is not, it's the Function.prototype. It should be right "below" the function f:

         f
         |
         v
 Function.prototype
         |
         v
  Object.prototype
         |
         v
        null

Notice how the prototype is listed as Object, in the form of key/value pair prototype: Object

What you see as the .prototype property of f, is the function's own prototype object - assume f would be a constructor, then all new f instances would inherit from f.prototype.

meaning that function f inherits directly from Object.

Nope. The public .prototype property must not be confused with the internal prototype chain (usually denoted as [[prototype]] internal property). You can access the prototype chain with Object.getPrototypeOf. More information about that at __proto__ VS. prototype in JavaScript, maybe Why functions prototype is chained repeatedly? or http://eloquentjavascript.net/chapter8.html.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Your diagram is exactly how I understand JavaScript inheritance... but the console log statements don't correspond thereto! 1. Function.prototype is not listed "below" the function 'f' 2. Object.getPrototypeOf(f) yields `function Empty() {}`. o.O? Where does this fit into the puzzle? 3. If you would kindly recommend a link for further reading regarding the public and internal prototype properties, it would be very helpful. – kmiklas Jan 23 '14 at 21:51
  • You'll also find that using (function Empty() {}).isPrototypeOf(f) will yield false, even though that is what it told you the prototype was in the first place. – Mike Jan 23 '14 at 21:56
  • @kmiklas: 1. I don't know which browser (which console) you are using. `console.dir` shows at least the own properties (including that `.prototype`), maybe the prototype chain objects in an expandable list. If not, try `console.log(f)` instead. 2. Yes, that `Object.getPrototypeOf(f) === Function.prototype` will be displayed as `function Empty() {}` - notice when you're pasting it you're creating another function. Try `Function.prototype.isPrototypeOf(f)` :-) – Bergi Jan 23 '14 at 21:56
  • @kmiklas: f does not inherits from Function (`f instanceof Function`), it is an instance of Function. I think this is the source of your confusion. – Andrea Parodi Jan 23 '14 at 22:10
0

I'm starting at the beginning for people who come to this thread looking for info.

kmiklas can ignore everything and just jump to the link at the end. Anyone else who isn't sure about Javascript should continue reading below.

//STARTING AT THE BEGINNING.

In JavaScript almost everything is an object. Even primitive datatypes (except null and undefined) can be treated as objects.

Booleans can be objects or primitive data treated as objects Numbers can be objects or primitive data treated as objects Strings are also objects or primitive data treated as objects Dates are always objects Maths and Regular Expressions are always objects Arrays are always objects Even functions are always objects

JavaScript is an object oriented language, but JavaScript does not use classes.

In JavaScript you don't define classes and create objects from these classes (as in most other object oriented languages).

JavaScript is prototype based, not class based.

Every object in Javascript has a prototype. When a messages reaches an object, JavaScript will attempt to find a property in that object first, if it cannot find it then the message will be sent to the object’s prototype and so on. This works just like single parent inheritance in a class based language.

Prototype inheritance chains can go as long as you want. But in general it is not a good idea to make long chains as your code can get difficult to understand and maintain.

-------> More info on Prototypes and Javascript (VERY USEFUL!!!) <-------

Mike
  • 874
  • 1
  • 8
  • 15
  • Thanks for your contribution, but you should not post stuff unrelated to the question. Imagined gone, all what is left is a [link only answer](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers). You either might have made a comment on the question with your link, or include the relevant parts of that blog post in your answer (as a citation) – Bergi Jan 23 '14 at 21:54
0

I think you misunderstood javascript prototype chain. Try this in the console:

function AnObject(){

}

AnObject.prototype = {
    aMethod: function() {
        return "hi";
    }
}

new AnObject().aMethod() now return "hi".

You see that AnObject.prototype could not return AnObject ancestor: in fact, it is meant to be overwritten with methods to be copied on AnObject instances.

AnObject.prototype now return

{
   aMethod: function() {
        return "hi";
   }
}

If you want to know type of AnObject function, you can use AnObject.constructor, and you'll get function Function() { [native code] }

Andrea Parodi
  • 5,534
  • 27
  • 46