x不是函数...你期望Object.create对构造函数做什么

Ken*_*Kin 7 javascript

对于这个问题,我不期望解决问题的方法,但希望更好地理解事情.

一些引用规格:

  • 5.1版(链接)

    §15.2.3.5Object.create(O [,Properties])

    create函数使用指定的原型创建一个新对象.调用create函数时,将执行以下步骤:

    1. 如果Type(O)不是Object或Null则抛出TypeError异常.
    2. 设obj是创建一个新对象的结果,好像是通过表达式new Object(),其中Object是具有该名称的标准内置构造函数
    3. 将obj的[[Prototype]]内部属性设置为O.
    4. 如果参数Properties存在且未定义,则将自己的属性添加到obj,就好像通过调用带有参数obj和Properties的标准内置函数Object.defineProperties一样.
    5. 返回obj.
  • 第6版 - 草稿(链接)

    §19.1.3.2Object.create(O [,Properties])

    create函数使用指定的原型创建一个新对象.调用create函数时,将执行以下步骤:

    1. 如果Type(O)不是Object或Null则抛出TypeError异常.
      1. 设obj是带参数O的抽象操作ObjectCreate的结果.
      2. 如果参数属性存在且未定义,则a.返回抽象操作ObjectDefineProperties(obj,Properties)的结果.
      3. 返回obj.

如果我理解正确,两个规范都允许执行以下代码:

function F() {
}

var x=Object.create(F);

// a minimal test
alert(x.prototype.constructor===F); // true
alert(x instanceof Function) // true
alert(typeof x) // 'object'
Run Code Online (Sandbox Code Playgroud)

似乎它创建了一个类型的对象派生自(抱歉可怜的术语..), Function因为我在FireFox中测试过,因此x不可调用的:

x(); // x is not a function 
Run Code Online (Sandbox Code Playgroud)

我在考虑为什么它不会禁止使用构造函数O或只是创建一个有效的构造函数.

所以我想知道你期望Object.create对构造函数做什么?

bfa*_*tto 4

不幸的是,这行不通。你所拥有的是一个F在其原型链中的对象;函数本身F并不构成x函数。

只有通过函数声明或函数表达式创建的对象才会将“Function”作为其 [[Class]] 和 [[Call]] 方法,这使其可调用。这些是根据ECMAScript 5 规范第 13.2 节中详细说明的步骤创建的。

的算法Object.create做了一些不同的事情,正如您在报价中看到的那样。在您的情况下,x将是一个具有 [[Class]]“对象”且没有 [[Call]] 方法的常规对象。如果你尝试Object.prototype.toString.call(x),你会得到"[object Object]",其中“Object”是 的 [[Class]] xx instanceof Function只返回,true因为构造函数是(via )Function原型链的一部分。xF

我不确定 ES6 中是否会改变这些,但我想不会。