JavaScript对象的元素是否按特定顺序初始化?

6
我有一个类似这样的函数:
parsers[1] = function(buf) {
    return {
        type: "init",
        name: buf.readUTF8String(),
        capacity: buf.readUInt32(),
        port: buf.readUInt16()
    };
}

我是否有任何保证,namecapacityport 会按顺序初始化?否则,缓冲区将以错误的顺序读取。

当然,我可以退而求其次:

parsers[1] = function(buf) {
    var ret = {type: "init"};
    ret.name = buf.readUTF8String();
    ret.capacity = buf.readUInt32();
    ret.port = buf.readUInt16();

    return ret;
}

3
这是 ES5 规范的相关部分:11.1.5 - 对象初始化器 - joews
@joews:有点晦涩,但我理解它们是按顺序评估的。谢谢。 - coyotte508
@joews 他想要一个__保证__,而不是学术猜测。 - Axel Amthor
猜测一下?如果有答案的话,它就在那个文件里。我无法解读那部分内容,所以我在帮助中贴了一个链接,希望能帮助其他人回答这个问题。 - joews
2
如果你正在编写期望在对象初始化器的值侧中调用函数/方法调用以特定顺序(因为副作用)的代码,那么我建议你停止这样做,并按所需顺序编写具体的逐行步骤。为什么要编写如此困难的代码,以知道所有Javascript实现是否完全相同?如果顺序很重要,而且不是100%明显所有实现都按照你想要的方式执行初始化器,则要安全并自己编码顺序。 - jfriend00
2个回答

3

感谢@joews的评论,我可以回答自己的问题。

从链接11.1.5对象初始化程序中:

语法

ObjectLiteral

  • { }

  • { PropertyNameAndValueList }

  • { PropertyNameAndValueList , }

PropertyNameAndValueList

  • PropertyAssignment

  • PropertyNameAndValueList,PropertyAssignment

简而言之,对象构造函数接受参数为:无、初始化值列表或初始化值列表后跟逗号。

该初始化值列表由PropertyAssignment或初始化值列表后跟PropertyAssignment组成,基本上是通过递归的PropertyAssignment列表。

现在的问题是在最后一个PropertyNameAndValueList,PropertyAssignment中,这两个部分是否有特定的顺序进行评估?

产生式 PropertyNameAndValueList : PropertyNameAndValueList , PropertyAssignment 的评估如下:

  1. obj为评估PropertyNameAndValueList的结果。

  2. propId为评估PropertyAssignment的结果。

  3. ...

如果确保2.紧随1.后,则可以保证顺序。

来自5.2算法约定:

规范通常使用编号列表来指定算法中的步骤。这些算法用于精确地指定 ECMAScript 语言结构所需的语义。算法并不意味着要使用任何特定的实现技术。在实践中,可能有更有效的算法可用于实现给定的功能。 ... 为了表达清晰,算法步骤可以细分为顺序子步骤。 所以,从我所了解的情况来看,期望的初始化顺序是一个接一个地对元素进行初始化。

0

和其他许多编程语言一样,我不会依赖于对象属性的任何“顺序”,也不会依赖于它们的初始化方式或值的分配方式。

如果需要“外部”顺序,则可以尝试使用这些属性的映射来实现。


1
这与对象内实际属性的顺序无关,而是与初始化时表达式的顺序是否被尊重有关(由于函数调用可能产生副作用,因此很重要)。 - Qantas 94 Heavy
如果你看了Axel的回答,他就是这么说的。你的回复读起来像是你刚好写到“nor”这个词之前。 - Matthew Whited
你是在说你个人不会假设属性没有按顺序分配,还是你有证据证明它们不是?如果是后者,你能提供一些引用吗?谢谢! - CodingIntrigue
2
@RGraham 我不会依赖它,为了代码的清晰度,我不会使用任何形式的“隐藏功能”。我建议通过可见的应用逻辑来实现任何必要的排序。也许很难划定停止的界限,因为最终你必须依赖于某些东西,但代码的清晰度仍然是非常重要的。想象一下半年后有人正在更改缓冲函数的行为 - ... - Axel Amthor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接