对于这个问题,我不期望解决问题的方法,但希望更好地理解事情.
一些引用规格:
5.1版(链接)
§15.2.3.5Object.create(O [,Properties])
create函数使用指定的原型创建一个新对象.调用create函数时,将执行以下步骤:
- 如果Type(O)不是Object或Null则抛出TypeError异常.
- 设obj是创建一个新对象的结果,好像是通过表达式new Object(),其中Object是具有该名称的标准内置构造函数
- 将obj的[[Prototype]]内部属性设置为O.
- 如果参数Properties存在且未定义,则将自己的属性添加到obj,就好像通过调用带有参数obj和Properties的标准内置函数Object.defineProperties一样.
- 返回obj.
第6版 - 草稿(链接)
§19.1.3.2Object.create(O [,Properties])
create函数使用指定的原型创建一个新对象.调用create函数时,将执行以下步骤:
- 如果Type(O)不是Object或Null则抛出TypeError异常.
- 设obj是带参数O的抽象操作ObjectCreate的结果.
- 如果参数属性存在且未定义,则a.返回抽象操作ObjectDefineProperties(obj,Properties)的结果.
- 返回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对构造函数做什么?
不幸的是,这行不通。你所拥有的是一个F在其原型链中的对象;函数本身F并不构成x函数。
只有通过函数声明或函数表达式创建的对象才会将“Function”作为其 [[Class]] 和 [[Call]] 方法,这使其可调用。这些是根据ECMAScript 5 规范第 13.2 节中详细说明的步骤创建的。
的算法Object.create做了一些不同的事情,正如您在报价中看到的那样。在您的情况下,x将是一个具有 [[Class]]“对象”且没有 [[Call]] 方法的常规对象。如果你尝试Object.prototype.toString.call(x),你会得到"[object Object]",其中“Object”是 的 [[Class]] x。x instanceof Function只返回,true因为构造函数是(via )Function原型链的一部分。xF
我不确定 ES6 中是否会改变这些,但我想不会。