Javascript `ECMAScript规范中的新对象`vs`Object`
因此,我正在研究ES5规范中的Javascript `ECMAScript规范中的新对象`vs`Object`,javascript,language-lawyer,ecmascript-5,Javascript,Language Lawyer,Ecmascript 5,因此,我正在研究ES5规范中的新对象和对象的定义。令我惊讶的是: newobject描述了对象构造函数如何工作的整个算法-处理不同类型的值所发生的事情。基本上在非对象上调用ToObject——对象上的标识,并在null和未定义的基础上构建 Object对于null和undefined有一个特殊的第一步,它构建一个对象,然后在原语上调用ToObject,在对象上调用identity 在读了几遍描述之后,它们看起来是一样的。然而,很明显,从规范来看,他们做了一些不同的事情。例如,在数组中,调用新
新对象
和对象
的定义。令我惊讶的是:
描述了对象构造函数如何工作的整个算法-处理不同类型的值所发生的事情。基本上在非对象上调用newobject
——对象上的标识,并在null和未定义的基础上构建ToObject
对于null和undefined有一个特殊的第一步,它构建一个对象,然后在原语上调用Object
,在对象上调用identityToObject
数组
中,调用新数组
被指定为
所以-新对象和对象之间的区别是什么?为什么它们的指定不同?
为方便起见-这里有一个。对象(窗口)
永远不会克隆窗口
,但新对象(窗口)
可能会。所有当前的(可能是所有已知的)实现只返回相同的引用,尽管规范允许实现定义的行为
15.2.1.1的步骤是:
ToObject
(9.9)的定义列出了步骤1(表14)将捕获的几种类型,但对于对象
有一个非常简单的定义:
结果是输入参数(无转换)
它明确声明输入参数将按原样返回,因此它们应该是相等的引用(==
)
新对象的定义(15.2.2.1)在步骤1中具有类似的类型检查链,但对象的步骤(1.a)是:
一,。如果该值是本机ECMAScript对象,则不要创建新对象,只需返回值即可
二,。如果该值是一个主机对象,则将执行操作,并以依赖于实现的方式返回结果,这可能取决于主机对象
也就是说,对于任何主机对象foo
,调用对象(foo)
必须==foo
,但是新对象(foo)
可能==foo
主机对象在4.3.8中定义为
对象,以完成ECMAScript的执行环境
列出了一些要包括窗口
、历史
等的主机对象。通过新对象(foo)
运行这些对象应该(但不一定)返回不同的对象
在任何情况下,除了传递宿主对象之外,newobject(foo)
似乎是一个更复杂的链,它以与object(foo)
几乎相同的方式遵从ToObject
不幸的是,15.2.2.1.1.a.ii声明“结果以依赖于实现的方式返回”,并且没有关于“所采取的行动”的细节,而且Chrome似乎将为所有列出的“主机对象”返回相同的对象(相等的引用)
使用此脚本检查:
var对象=[
/*本机对象*/
'Object'、'Date'、'Math'、'parseInt'、'eval',
/*宿主对象*/
“窗口”、“文档”、“位置”、“历史记录”、“XMLHttpRequest”、“设置超时”
];
函数getDefinedReference(名称){
如果(eval('typeof'+name)!='undefined'){
返回eval(名称);
}否则{
抛出新错误(“”+name+’未定义。“);
}
}
函数checkIdentity(名称){
试一试{
var ref=getDefinedReference(名称);
var no=新对象(参考);
var o=对象(参考);
log(name,ref==no,ref==o,no==o);
如果(ref==o&&no!==o){
//确保ref==对象(ref),但不是新对象(ref)
log(名称为“返回不同的引用”);
}
}捕获(e){
控制台。警告(e);
}
}
对象。forEach(checkIdentity);
如果(窗口类型!==“未定义”){
用于(窗口中的var f){
支票身份(f);
}
}
JS room的人(即Jan Drovak)猜测这与主机对象有关,但我无法找出一个真正的区别。new Object
是在主机对象上定义的实现。我仍然希望看到一个例子,说明它何时不是一个标识。这将是一个著名的问题吗?当对象作为新表达式的一部分被调用时,它是一个可以创建对象的构造函数。
这涉及到如果值是一个宿主对象,然后执行操作并以依赖于实现的方式返回结果,该方式可能取决于主机对象。
这取决于实现ToObject
-对象:结果是输入参数(无转换)。
这似乎是主要区别。为什么?可能要允许依赖于实现的部分
为什么不继续询问?您能否找到一个实现和一个主机对象,它们在对象
和新对象
之间有所不同?@BenjaminGruenbaum仍在寻找。我强烈怀疑这是规范允许的,但没有人在使用,但测试套件不会有什么坏处。@AwalGarg两个新创建的对象引用不相等-与{}=={}
@AwalGarg相同整个问题依赖于第二部分,其中它不是null/未定义:-)