允许重复的属性名称的目的是什么?

IT技术 javascript standards ecmascript-6
2021-02-23 01:35:03

我正在阅读MDN javascript 参考,因此以下代码不再返回false

function haveES6DuplicatePropertySemantics(){
  "use strict";
  try {
    ({ prop: 1, prop: 2 });

    // No error thrown, duplicate property names allowed in strict mode
    return true;
  } catch (e) {
    // Error thrown, duplicates prohibited in strict mode
    return false;
  }
}

在 ECMAScript 5 严格模式代码中,重复的属性名称被视为 SyntaxError。随着计算属性名称的引入使得运行时重复成为可能,ECMAScript 6 取消了这个限制。

我的问题是,在初始值设定项中允许重复的属性名称有什么实际好处?我可以看到,当对象属性被动态分配时,这有时可能会发生,但由于优先顺序显然决定了在新创建的对象上实际设置了哪些属性——这似乎比最好避免的不确定行为更重要。

1个回答

在初始值设定项中允许重复的属性名称有什么实际好处

没有这样的实际好处。现在 ECMA Script 6 中有计算属性键,键的实际值将仅在运行时确定。事实上,键可以在运行时添加到对象中,它们会覆盖现有的键和值。ES-6 中扩展了相同的行为,并且删除了不允许编译时重复键检查的限制。

ESDiscuss 邮件列表中讨论中引用 Allen Wirfs-Brock

计划是对任何包含计算属性键和当前规范的对象文字执行运行时验证。草稿包含用于进行检查的伪代码。然而,错误报告 ( https://bugs.ecmascript.org/show_bug.cgi?id=1863 ) 指出了当前规范的一个问题。例如,当前规范。引发错误:

({get a() {},
   get ["a"]() {}
 });

但不是:

({get ["a"]() {},
   get a() {}
 });

基本上,在处理包含计算键的属性定义时,仅检查已定义的属性键是不够的。如果存在任何计算键,即使对于具有文字属性名称的定义也必须进行检查。仅仅考虑属性键和数据/访问器属性的区别是不够的,验证还必须考虑定义的句法形式以及是否适用严格模式..

事实证明,即使在伪代码中,这也是一套相当复杂的运行时验证规则。我很难说服自己这种动态验证的运行时计算和元数据成本是合理的。成本太高,实际收益很小。

出于这个原因,我建议我们放弃对象文字(和类定义)的这种运行时验证。对于没有计算键的属性定义,我们仍然会有静态验证和早期错误。但是任何通过这些检查的东西(包括所有具有计算名称的属性定义)都只是按顺序处理,没有重复名称检查。

因此,提案是保留对普通键的编译时检查,根据此评论,该检查稍后被删除。修订版 26 中

消除了对对象文字和类定义的重复属性名称限制

尽管添加键(这将具有明确的优先级)但使用两个相同的键进行初始化{prop: 1, prop:2}(至少我认为优先级有点令人惊讶)。无论如何,它们在运行时都不确定吗?我不确定为什么你提供的参考文献也没有提到严格模式?
2021-04-16 01:35:03
@Xotic750 在附件 E 中提到-In ECMAScript 2015, it is no longer an early error to have duplicate property names in Object Initializers.
2021-04-19 01:35:03
好的,谢谢你指出我的参考。对我来说,删除这样一个早期的错误似乎很奇怪。除了可能的编码困难之外,我不明白其背后的原因。
2021-04-20 01:35:03
因此,您认为编写编译时检查代码、维护 ES5 中定义的“严格”规则太困难了,而只是让“严格”不那么“严格”以符合 ES6 计算属性键会更容易。或者它实际上写在当前的ES6规范中必须删除它,我在规范中找不到答案?
2021-04-22 01:35:03
@user3467349 对象文字中的键将从左到右进行处理。并且参考文献没有提到任何关于严格模式的内容,因为无论模式如何,都不会进行此检查。
2021-05-01 01:35:03