21

假设我有一个对象,它根据函数的返回值分配属性:

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 规范中指定?我只是出于教育原因而问。

谢谢。

4

5 回答 5

18

标准 ECMA-262 (5.1) - 第 11.1.5 节 - 对象初始化器

产生式 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.

所以是的,该命令由标准强制执行。

于 2013-04-24T19:37:56.207 回答
1

来自 ECMAScript 6 wiki,它将定义新版本的 JS:

当一个范围(Block、FunctionBody、Program、ModuleBody 等)被输入时,所有直接包含的函数和类声明所声明的变量都绑定到它们各自的函数和类。然后所有类体都按文本顺序执行。当评估类定义时,类主体定义并初始化类范围的属性一次。这包括构造函数(“类”本身)及其原型属性的属性。这些初始化以文本顺序发生

你的资源来了!JavaScript 对象属性以对象的文本顺序初始化。数组(当前)并不总是遵循这个规则。

来源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以及属性在内部表中的位置。

于 2013-04-24T19:37:19.190 回答
0

我没有官方来源可以引用,但让我们使用一点常识。

如果作业没有按顺序完成怎么办?您永远无法知道哪个值将分配给哪个属性,从而使对象结构无用(至​​少在使用对象字面量语法时)

如果它是函数调用、原始文字或其他值,则没有区别。如果不能保证按顺序发生,那就行不通了。


在 ECMAScript 5 中快速搜索该术语left to right后,如果对您有帮助,以下是一些结果:

7 词汇约定

ECMAScript 程序的源文本首先被转换为一系列输入元素,这些元素是标记、行终止符、注释或空格。从左到右扫描源文本,重复将最长可能的字符序列作为下一个输入元素。

11.8.5 抽象关系比较算法

...这是必要的,因为 ECMAScript 指定表达式的从左到右求值。

附录 D(资料性)第 5 版中可能对第 3 版兼容性产生影响的更正和澄清

ECMAScript 通常使用从左到右的求值顺序,但是 > 和 <= 运算符的第 3 版规范语言导致部分从右到左的顺序。该规范已针对这些运算符进行了更正,现在它指定了一个完整的从左到右的评估顺序。

于 2013-04-24T19:29:30.750 回答
0

分配总是有序的。这只是代码被发现、解释和执行的方式。

于 2013-04-24T19:19:15.387 回答
0

是的,您可以保证 a 为 1,b 为 2,等等。每个都f()将按照您编写它们的顺序进行解释。

于 2013-04-24T19:19:28.603 回答