因此,我在new Object
和Object
的定义中查看ES5规范。令我惊讶的是:
new Object
描述了对象构造函数如何工作的整个算法 - 处理不同类型的值所发生的事情。基本上在非对象上调用ToObject
- 对象上的标识和构建为null和undefined。Object
有一个特殊的第一步,用于null和undefined,它构建一个对象,然后在对象的原语和标识上调用ToObject
。几次阅读说明后 - 他们似乎相同。但是,从规范中可以清楚地看出它们某些是不同的。例如,在Array
中,调用new Array
被指定为 the function call Array(…)
is equivalent to the object creation expression new Array(…)
with the same arguments.`
所以 - new Object
和Object
之间有什么区别?他们为什么以不同的方式指定?
为方便起见 - 这是一个link to the spec。
答案 0 :(得分:16)
Object(window)
永远不会克隆window
,但可能会new Object(window)
。所有当前 - 可能都是已知的 - 实现只返回相同的引用,尽管规范允许实现定义的行为。
15.2.1.1的步骤说:
- 如果value为null,未定义或未提供,则创建并返回一个新的Object对象,就像使用相同的参数调用标准的内置Object构造函数一样
- 返回ToObject(值)。
醇>
ToObject
(9.9)的定义列出了将在步骤1(表14)中捕获的几种类型,但Object
的定义非常简单:
结果是输入参数(无转换)。
它明确声明输入参数将按原样返回,因此它们应该是相等的引用(===
)。
new Object
(15.2.2.1)的定义在步骤1中具有类似的类型检查链,但对象(1.a)的步骤是:
我。如果值是本机ECMAScript对象,则不要创建新对象,只需返回值。
II。如果该值是宿主对象,则执行操作并以依赖于实现的方式返回结果,该方式可能取决于宿主对象。
也就是说,对于任何主机对象foo
,来电Object(foo)
必须=== foo
,new Object(foo)
可能=== foo
。
主机对象在4.3.8中定义为
主机环境提供的对象,以完成ECMAScript的执行环境。
This answer列出了一些要包含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);
}
}
找不到Object
和new Object
行为不同的任何对象。 @ Xotic750似乎是正确的,它可以依赖于实现,但没有人使用它。