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

use*_*243 13 javascript function object

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

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

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

那么,有人可以澄清对象是第一个还是功能?什么是根.

bfa*_*tto 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
Run Code Online (Sandbox Code Playgroud)

ECMAScript 5.1规范声明如下:

  1. 15.3.4函数原型对象的属性中:

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

  2. 并且在15.2.4对象原型对象的属性中

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


Mat*_*ick 8

下面介绍一下MDN文档Object.prototype不得不说:

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

换句话说,几乎是所有对象Object.prototype的根.这两个和是孩子,这本身就是一个孩子.ObjectFunctionFunction.prototypeObject.prototype

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

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

您可以使用这个小片段(这里有用的文档)轻松调查原型链:

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

根据这个函数,原语没有原型:

> getPrototypes(3)
TypeError: Object.getPrototypeOf called on non-object
Run Code Online (Sandbox Code Playgroud)

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

  • Object.create(null)
  • Object.prototype中
    • arguments
    • Object.create(Object.prototype)
    • {}
      • Object.create({}) - 假设{}是前一行的对象,而不是单独的新对象
    • JSON
    • 数学
    • Array.prototype
      • []
      • new Array()
    • Function.prototype的
      • 排列
      • 宾语
      • 功能
      • 布尔
      • 正则表达式
      • 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/

这非常令人困惑!请注意,对于大多数情况,X.prototype不是原型X!如果我们有一些更好的术语,情况可能会有所改善; 但是......我们不:(正如你可以看到,构造等Number,并Boolean在一个独立的子hieararchy从他们所生产的对象.另外,Object本身继承Function.prototype自继承Object.prototype.

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

  1. 一个对象可以是多个构造函数的实例:str1 instanceof String并且str1 instanceof Object都是正确的.这不会反映在constructor财产中:str1.contructor === String

  2. 有时,我们找不到对象原型链中每个对象的构造函数: Object.getPrototypeOf(str2).constructor === String.这是因为该constructor属性继承自String.prototype:both str1.hasOwnProperty('constructor')str2.hasOwnProperty('constructor')false,而Object.getPrototypeOf(str1).hasOwnProperty('constructor')为true.幸运的是,您可以使用此Object.prototype.isPrototypeOf方法代替: str1.isPrototypeOf(str2)是真的.