admin管理员组

文章数量:1192932

In JavaScript is Object the root of all entities or Function is the root?

For example in the following source objects-functions-and-prototypes-in.html, first the author says "Every entity in Javascript is an object", and later it says "any new object can only be created as an instance of a function (even when you do 'var a = new Object;', Object is a function btw)". The author is basically contradicting himself as far as I can see.

And I see the same chaotic comments in so many other resources on JavaScript. In Java it is easy, you know the first entity in any class Hierarchy is the Object class, but in JavaScript, all I see is chaos.

So, can someone please clarify if Object comes first or Function? What is the root.

In JavaScript is Object the root of all entities or Function is the root?

For example in the following source objects-functions-and-prototypes-in.html, first the author says "Every entity in Javascript is an object", and later it says "any new object can only be created as an instance of a function (even when you do 'var a = new Object;', Object is a function btw)". The author is basically contradicting himself as far as I can see.

And I see the same chaotic comments in so many other resources on JavaScript. In Java it is easy, you know the first entity in any class Hierarchy is the Object class, but in JavaScript, all I see is chaos.

So, can someone please clarify if Object comes first or Function? What is the root.

Share Improve this question asked Jan 4, 2013 at 17:38 user1888243user1888243 2,6819 gold badges36 silver badges46 bronze badges 2
  • The simple answer is the root of a prototype chain will always be Object.prototype, weird user manipulation aside. – Dagg Nabbit Commented Jan 4, 2013 at 19:37
  • Clearly the ultimate root of any prototype chain is null! – Bergi Commented Sep 19, 2023 at 22:58
Add a comment  | 

3 Answers 3

Reset to default 11

I believe the end of the line is Object.prototype, which is an object. This is what makes me think so:

Function.prototype;                    // the empty function object
Function.prototype.__proto__;          // the default Object prototype
Object.prototype;                      // the default Object prototype
Object.prototype.__proto__;            // null

The ECMAScript 5.1 specification states it like this:

  1. In 15.3.4 Properties of the Function Prototype Object:

    The value of the [[Prototype]] internal property of the Function prototype object is the standard built-in Object prototype object

  2. And in 15.2.4 Properties of the Object Prototype Object

    The value of the [[Prototype]] internal property of the Object prototype object is null

Here's what the MDN docs for Object.prototype have to say:

all objects inherit methods and properties from Object.prototype, although they may be overridden (except an Object with a null prototype, i.e. Object.create(null)).

In other words, Object.prototype is the root of almost all objects. Both Object and Function are children of Function.prototype, which is itself a child of Object.prototype.

I find inheritance in Javascript to be far easier to understand when I ignore the constructor functions, and instead focus on prototype chains. Doing this, for me, makes both the questions as well as the answers simpler; questions like:

  • what is the prototype chain of an object?
  • given two objects x and y, is x in y's prototype chain? (or: does y inherit from x?)

You can easily investigate prototype chains yourself with this little snippet (helpful docs here):

function getPrototypes(obj) {
    var protos = [],
        parent = obj;
    while ( true ) {
        parent = Object.getPrototypeOf(parent);
        if ( parent === null ) {
            break;
        }
        protos.push(parent);
    }
    return protos;
}

According to this function, primitives don't have prototypes:

> getPrototypes(3)
TypeError: Object.getPrototypeOf called on non-object

So let's leave primitives out of the picture. For objects, the hierarchy looks like this (where the children are indented to the right of their parent). As far as I know, true multiple inheritance is impossible in Javascript, and so every object has a single parent, with the exception of Object.prototype, which has no parent:

  • Object.create(null)
  • Object.prototype
    • arguments
    • Object.create(Object.prototype)
    • {}
      • Object.create({}) -- assuming {} is the object from the previous line, not a separate new object
    • JSON
    • Math
    • Array.prototype
      • []
      • new Array()
    • Function.prototype
      • Array
      • Object
      • Function
      • Number
      • Boolean
      • String
      • RegExp
      • function MyFunction() {}
      • Object.keys
      • Object.prototype.toString
      • Object.prototype.toString.call
      • getPrototypes
    • MyFunction.prototype
      • new MyFunction()
    • String.prototype
      • new String('abc')
        • Object.create(new String('abc'))
    • Number.prototype
      • new Number(41)
    • Boolean.prototype
      • new Boolean()
      • new Object(false)
    • RegExp.prototype
      • /a/

This is very confusing! Notice that for most cases, X.prototype is not a prototype of X! If we had some better terminology, the situation would probably be improved; however ... we don't :( As you can see, constructors such as Number and Boolean are in a separate sub-hieararchy from the objects they produce. Also, Object itself inherits from Function.prototype inherits from Object.prototype.

If you try these examples out, you will also find that using the constructor property is a poor way to inspect an object's prototypes, for a couple of reasons. Given var str1 = new String('abc'); var str2 = Object.create(str1);, here's why:

  1. an object can be an instance of multiple constructors: str1 instanceof String and str1 instanceof Object are both true. This isn't reflected in the constructor property: str1.contructor === String

  2. sometimes, we can't find a constructor function for each object in an object's prototype chain: Object.getPrototypeOf(str2).constructor === String. This is because the constructor property is inherited from String.prototype: both str1.hasOwnProperty('constructor') and str2.hasOwnProperty('constructor') are false, while Object.getPrototypeOf(str1).hasOwnProperty('constructor') is true. Fortunately, you can use the Object.prototype.isPrototypeOf method for this instead: str1.isPrototypeOf(str2) is true.

You're misunderstanding it.

Everything in Javascript (including all functions) is an object.

However, every object is an instance of a function. (as specified by the object's constructor property)

本文标签: In JavaScriptwhat is the ultimate rootObject or FunctionStack Overflow