7

对于这个问题,我不希望有一个解决方案来解决问题,而是想更好地理解问题..

规范中的一些引用:

  • 5.1版(链接

    §15.2.3.5 Object.create(O [,属性])

    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. 返回对象。
  • 第 6 版 - 草稿 (链接)

    §19.1.3.2 Object.create(O [,属性])

    create 函数创建一个具有指定原型的新对象。调用 create 函数时,会执行以下步骤:

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

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

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'

正如我在 FireFox 中测试的那样,它似乎创建了一个派生自(对不起,术语不好..) Function类型的对象,因此x不可调用的

x(); // x is not a function 

我正在考虑为什么它不允许将构造函数用作O或仅创建有效的构造函数。

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

4

2 回答 2

4

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

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

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

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

于 2013-10-04T18:54:28.527 回答
2

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

我当然希望它遵循规范……</p>

我在想为什么它也不允许构造函数用作 O

为什么要呢?每个构造函数都是一个对象(第 8.6 节)

…或者只是创建一个有效的构造函数。

规范说它应该创建一个普通对象(如 by new Object),其 [[prototype]] 设置为 O。普通对象不是函数,它们没有 [[call]] 或 [[construct]] 属性。它也将有 [[class]] Object,而不是Function

x.prototype.constructor===F // true
x instanceof Function // true
typeof x // 'object'

似乎它创建了一个类型的对象,该类型派生自(对不起,糟糕的术语..)函数

F,实际上。它确实继承了.prototype属性F(这就是为什么你的第一个测试是true),并且通过F它也继承了Function.prototypewhich make it instanceof Function。然而,它没有 [[call]] 属性(它是不可调用的),所以typeof没有 yield "function",而只是"object".

于 2013-10-05T19:56:08.123 回答