ECMAScript规范中的`new Object` vs`Object`

Ben*_*aum 43 javascript language-lawyer ecmascript-5

所以,我在定义什么new ObjectObject做什么时看着ES5规范.出乎我的意料:

  • new Object描述了对象构造函数如何工作的整个算法 - 处理不同类型的值所发生的事情.基本上调用ToObject非对象 - 对象上的标识和构建在null和undefined上.
  • Object在null和undefined中有一个特殊的第一步,它构建一个对象,然后调用对象ToObject上的基元和标识.

在阅读了几次描述之后 - 它们看起来完全相同.但是,很明显,从规范中他们做不同的事情.例如,在Array调用new Array中指定函数调用Array(…)等同于new Array(…)具有相同参数的对象创建表达式

那么 - 之间有什么区别?为什么他们指定不同?new ObjectObject

为了方便 - 这里是规范链接.

ssu*_*ube 16

Object(window)永远不会克隆,windownew Object(window)可能.所有当前 - 可能是所有已知的 - 实现只返回相同的引用,尽管规范允许实现定义的行为.

15.2.1.1的步骤说:

  1. 如果value为null,undefined或not provided,则创建并返回一个新的Object对象,就像使用相同的参数调用标准的内置Object构造函数一样
  2. 返回ToObject(值).

ToObject(9.9)的定义列出了将在步骤1(表14)中捕获的几种类型,但是Object有一个非常简单的定义:

结果是输入参数(无转换).

它明确声明输入参数将按原样返回,因此它们应该是相等的引用(===).

new Object(15.2.2.1)的定义在步骤1中具有类似的类型检查链,但对象(1.a)的步骤是:

一世.如果值是本机ECMAScript对象,则不要创建新对象,只需返回值.

II.如果值是主机对象,则执行操作并以依赖于实现的方式返回结果,该方式可能取决于主机对象.

也就是说,对于任何主机对象foo,呼叫Object(foo)必须=== foonew Object(foo)可以=== foo.

主机对象在4.3.8中定义为

主机环境提供的对象,以完成ECMAScript的执行环境.

这个答案列出了一些主机对象包括window,history等运行那些通过new Object(foo) 应该(但并不一定)返回不同的对象.

在任何情况下,传递一个主机对象,new Object(foo)似乎是一个更复杂的链,与ToObject大致相同的方式Object(foo).

不幸的是,15.2.2.1.1.a.ii声明"结果以依赖于实现的方式返回"并且没有关于"采取的行动"的具体细节,并且看起来Chrome将返回相同的对象所有列出的"主机对象"(相同的引用).

使用此脚本检查:

var objects = [
  /* Native objects */
  'Object', 'Date', 'Math', 'parseInt', 'eval',
  /* Host objects */
  'window', 'document', 'location', 'history', 'XMLHttpRequest', 'setTimeout'
];

function getDefinedReference(name) {
  if (eval('typeof ' + name) !== 'undefined') {
    return eval(name);
  } else {
    throw new Error('' + name + ' is not defined.');
  }
}

function checkIdentity(name) {
  try {
    var ref = getDefinedReference(name);
    var no = new Object(ref);
    var o = Object(ref);

    console.log(name, ref === no, ref === o, no === o);

    if (ref === o && no !== o) {
      // Make sure ref === Object(ref) but not new Object(ref)
      console.log(name, 'returns different references.');
    }
  } catch (e) {
    console.warn(e);
  }
}

objects.forEach(checkIdentity);

if (typeof window !== 'undefined') {
  for (var f in window) {
    checkIdentity(f);
  }
}
Run Code Online (Sandbox Code Playgroud)

找不到任何对象,Objectnew Object行为和行为不同.@ Xotic750似乎是正确的,它可以依赖于实现,但没有人使用它.