假设我有一个对象根据函数的返回值分配属性:
var i = 0;
var f = function() { return ++i; }
var foo = {
a:f(),
b:f(),
c:f()
};
是否保证foo.a为1,foo.b为2,foo.c为3?我知道当你迭代一个对象时JS不保证顺序,那么赋值呢?
是否在JS规范中指定了?我只是出于教育原因。
感谢。
答案 0 :(得分:16)
Standard ECMA-262 (5.1) - Section 11.1.5 - Object Initialiser
生产PropertyNameAndValueList:PropertyNameAndValueList, PropertyAssignment的评估如下:
1. Let obj be the result of evaluating PropertyNameAndValueList. 2. Let propId be the result of evaluating PropertyAssignment. ... 5. Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false. 6. Return obj.
所以是的,订单是由标准强制执行的。
答案 1 :(得分:1)
来自ECMAScript 6 wiki,它将定义JS的新版本:
当输入范围(Block,FunctionBody,Program,ModuleBody等)时,所有直接包含的函数和类声明声明的变量将绑定到它们各自的函数和类。 然后所有课堂主体按文字顺序执行。在评估类定义时,类主体定义并初始化类范围的属性。这包括构造函数(“类”本身)及其prototype属性的属性。 这些初始化按文字顺序发生。
你的来源已经到了! JavaScript对象属性在文本顺序 on objects 上初始化。数组(目前)始终不遵循此规则。
来源:http://wiki.ecmascript.org/doku.php?id=harmony:classes
当我在ECMAScript 5中找到引用时,我会编辑这篇文章,虽然我确信它在那里。
ECMAScript 5确实拥有它:http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.7。
如果实现为for-in语句定义了特定的枚举顺序,则必须使用相同的枚举顺序对此算法的步骤3中的列表元素进行排序。
这定义了对DefineOwnProperty
的调用,从而定义了内部表中属性的位置。
答案 2 :(得分:0)
分配始终有序。它只是代码的查找,解释和执行方式。
答案 3 :(得分:0)
是的,保证a将为1,b为2,等等。每个f()
将按您编写的顺序进行解释。
答案 4 :(得分:0)
我没有官方消息来源引用,但让我们使用一点常识。
如果未按顺序完成,该怎么办?您永远不知道将哪个值分配给哪个属性,使对象结构无效(至少在使用对象文字语法时)。
如果是函数调用,原始文字或其他值,则没有区别。如果不保证按顺序发生,它就行不通。
在ECMAScript 5中快速搜索术语left to right
之后,如果它对您有帮助,可以使用以下结果:
7词汇约定
ECMAScript程序的源文本首先转换为一系列输入元素,即标记,行终止符,注释或空格。源文本从左向右扫描,重复使用尽可能长的字符序列作为下一个输入元素。
11.8.5抽象关系比较算法
...这是必要的,因为ECMAScript指定从左到右的表达式评估。
附录D(资料性附录)第5版中的更正和说明以及可能的第3版兼容性影响
ECMAScript通常使用从左到右的评估顺序,但是版本3规范语言用于>和< =运算符导致部分从右到左的顺序。已针对这些运算符更正了规范,现在它指定了从左到右的完整评估顺序。