Javascript 对象属性是否按顺序分配?

IT技术 javascript
2021-02-15 20:31:54

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

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

谢谢。

5个回答

标准 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.

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

来自 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对内部表中属性的调用以及属性的位置。

OP 既没有询问 ES6 类,也没有询问枚举或 for-in-loops。
2021-05-07 20:31:54
@Bergi:Object.defineProperties ( O, Properties )从来没有 for-in 循环,而且 ES6 类的大部分用途和属性都直接取自 ES5 对象。
2021-05-10 20:31:54

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

有资源总是好的:/
2021-04-18 20:31:54

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

由 javascript 解释器之神?
2021-04-16 20:31:54

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

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

无论是函数调用、原始文字还是其他值,都没有区别。如果不能保证它按顺序发生,它就是行不通的。


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

7 词汇约定

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

11.8.5 抽象关系比较算法

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

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

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

……如果你仔细想想,这是有道理的。当您使用 时.defineProperties(),您将传递一个对象字面量来创建属性。对象文字不是目标对象本身。需要枚举此对象文字以获取其信息,以便在目标对象上定义新属性。因此,如果实现定义了枚举顺序,则在内部枚举属性描述符时遵循相同的顺序是有意义的。
2021-04-23 20:31:54
枚举顺序是从第 11 节向上两步获取的,它是从 JSON 文字定义中获取的。我提供了一个链接,指向明确遵守实际顺序的地方——最后一步——而不是整个过程中的每一步。
2021-04-30 20:31:54
@SébastienRenauld:您的 ECMAScript 5 参考与所提出的问题无关。ES 实现在使用for-in. 该定义在设计上可能可靠或不可靠。您引用了 的定义defineProperties,它只是说明如果定义了枚举顺序,则该顺序将应用于属性的创建。这与对象字面量语法完全无关。
2021-05-04 20:31:54
@SébastienRenauld:这是对表达式求值顺序的一般参考,尽管要点没有改变。如果不能依赖顺序,对象字面量语法将毫无用处。
2021-05-14 20:31:54
在这种情况下,LTR 是关于语句的评估顺序,而不是属性顺序。他们所说的 LTR 是“a > b”,因为“a 大于 b”,而不是相反。我已经为 ECMAS5 和 6 提供了正确的段落。
2021-05-15 20:31:54