在JavaScript中,最终的根,对象或函数是什么?

时间:2013-01-04 17:38:23

标签: javascript function object

在JavaScript中,Object是所有实体的根,还是Function是根?

例如,在以下源objects-functions-and-prototypes-in.html中,首先作者说“Javascript中的每个实体都是一个对象”,后来它说“任何新对象只能作为函数的一个实例创建(即使你做'var a = new Object;',Object是一个函数btw)“。就我所见,作者基本上是自相矛盾的。

我在JavaScript上的许多其他资源中看到了同样的混乱评论。在Java中很容易,你知道任何类中的第一个实体Hierarchy是Object类,但在JavaScript中,我看到的只是混乱。

那么,有人可以澄清对象是先来还是功能?什么是根。

3 个答案:

答案 0 :(得分:9)

我相信该行的结尾是Object.prototype,这是一个对象。这就是让我这么想的原因:

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

ECMAScript 5.1规范如下所示:

  1. 15.3.4 Properties of the Function Prototype Object中:

      

    Function原型对象的[[Prototype]]内部属性的值是标准的内置Object原型对象

  2. 并在15.2.4 Properties of the Object Prototype Object

      

    Object原型对象的[[Prototype]]内部属性的值为null

答案 1 :(得分:8)

以下是Object.prototype Object.prototype所说的内容:

  

所有对象都从Object.prototype继承方法和属性,尽管它们可能被覆盖(除了具有null原型的Object,即Object.create(null))。

换句话说,Object几乎所有对象的根。 FunctionFunction.prototype都是Object.prototype的孩子,function getPrototypes(obj) { var protos = [], parent = obj; while ( true ) { parent = Object.getPrototypeOf(parent); if ( parent === null ) { break; } protos.push(parent); } return protos; } 本身就是> getPrototypes(3) TypeError: Object.getPrototypeOf called on non-object 的孩子。

当我忽略构造函数时,我发现Javascript中的继承更容易理解,而是专注于原型链。对我而言,这样做既可以使问题更简单,也可以使答案更简单;问题如:

  • 对象的原型链是什么?
  • 给出两个对象x和y,在y的原型链中是x吗? (或:是否继承自x?)

您可以使用此小片段轻松调查原型链(有用的文档MDN docs):

Object.prototype

根据此功能,here没有原型:

Object.create(null)

所以让我们把图元留下来。 对于对象,层次结构如下所示(子项缩进到其父项的右侧)。据我所知,真正的多重继承在Javascript中是不可能的,因此每个对象都有一个父对象,arguments除外,它没有父对象:

  • Object.create(Object.prototype)
  • 的Object.prototype
    • {}
    • Object.create({})
    • {}
      • [] - 假设new Array()是上一行的对象,而不是单独的新对象
    • JS​​ON
    • 数学
    • Array.prototype
      • function MyFunction() {}
      • Object.keys
    • Function.prototype的
      • 阵列
      • 对象
      • 功能
      • 布尔
      • 字符串
      • 正则表达式
      • Object.prototype.toString
      • Object.prototype.toString.call
      • getPrototypes
      • new MyFunction()
      • new String('abc')
    • MyFunction.prototype
      • Object.create(new String('abc'))
    • String.prototype
      • new Number(41)
        • new Boolean()
    • Number.prototype
      • new Object(false)
    • Boolean.prototype
      • /a/
      • X.prototype
    • RegExp.prototype
      • X

这非常令人困惑!请注意,对于大多数情况,Number不是Boolean的原型!如果我们有一些更好的术语,情况可能会有所改善;但是......我们没有:(正如你所看到的,ObjectFunction.prototype之类的构造函数与它们生成的对象位于一个单独的子层次中。此外,Object.prototype本身继承自constructor的{​​{1}}继承。

如果您尝试这些示例,您还会发现使用var str1 = new String('abc'); var str2 = Object.create(str1);属性是检查对象原型的一种不好的方法,原因有两个。给定str1 instanceof String,原因如下:

  1. 对象可以是多个构造函数的实例:str1 instanceof Objectconstructor都是真的。这不会反映在str1.contructor === String属性中:Object.getPrototypeOf(str2).constructor === String

  2. 有时,我们找不到对象原型链中每个对象的构造函数:constructor。这是因为String.prototype属性是从str1.hasOwnProperty('constructor')继承的:str2.hasOwnProperty('constructor')Object.getPrototypeOf(str1).hasOwnProperty('constructor')都是假的,而str1.isPrototypeOf(str2)是真的。幸运的是,您可以使用primitives方法代替:{{1}}为真。

答案 2 :(得分:3)

你误解了它。

Javascript中的所有内容(包括所有函数)都是一个对象。

但是,每个对象都是函数的实例。 (由对象的constructor属性指定)