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

x is not a function ... what would you expect Object.create to do with a constructor

本文关键字:create Object 期望 构造函数 什么 函数 一个      更新时间:2023-09-26

对于这个问题,我并不期望有解决方案来解决某些问题,但想更好地理解事情..

一些引用规格:

  • 版本 5.1(链接(

    §15.2.3.5 对象创建 ( O [, 属性] (

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

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

    §19.1.3.2 对象创建 ( O [, 属性] (

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

    1. 如果 Type(O( 不是 Object 或 Null,则引发 TypeError 异常。
      1. 让 obj 是带有参数 O 的抽象操作 ObjectCreate 的结果。
      2. 如果参数属性存在且未定义,则 一个。返回抽象操作 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'

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

x(); // x is not a function 

我在想为什么它不允许将构造函数用作O或只是创建一个有效的构造函数。

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

不幸的是,

这行不通。您拥有的是一个在其原型链中具有F的对象;F是一个函数这一事实并不能使x成为一个函数。

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

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

我不确定ES6中是否会改变其中的任何内容,但我想它不会。

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

当然,我希望它遵循规范...

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

为什么呢?每个构造函数都是一个对象 (§8.6(。

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

规范说它应该创建一个普通对象(如new Object(,其[[原型]]设置为O.普通对象不是函数,它们没有[[调用]]或[[构造]]属性。它还将具有[[类]]Object,而不是Function

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

似乎它创建了一个派生类型的对象(对不起,术语很差.功能

实际上,从F开始。它确实从F继承了.prototype属性(这就是为什么你的第一个测试是true(,并且通过F它也继承了Function.prototype,这使得它instanceof Function。然而,它没有[[调用]]属性(它不可调用(,所以typeof不会产生"function",而只是"object"