ES6是否为对象属性引入了定义明确的枚举顺序?
var o = {
'1': 1,
'a': 2,
'b': 3
}
Object.keys(o); // ["1", "a", "b"] - is this ordering guaranteed by ES6?
for(let k in o) {
console.log(k);
} // 1 2 3 - is this ordering guaranteed by ES6?
注意: 从ES2020开始,甚至更旧的操作(例如for- in
和)Object.keys
都必须遵循属性顺序。这不会改变以下事实:使用基本程序逻辑的属性顺序可能不是一个好主意,因为非整数索引属性的顺序取决于创建属性的时间。
ES2015-ES2019的答案:
对于for-in
,Object.keys
和JSON.stringify
: 第
对于一些其他操作: 是的 ,通常。
虽然ES6 / ES2015增加了财产秩序,它不需要for- in
,Object.keys
或者JSON.stringify
遵循这一顺序,由于传统的兼容性问题。
for-in根据[[Enumerate]]循环循环,[[定义为(强调我的):
调用O的[[Enumerate]]内部方法时,将执行以下步骤:
返回一个Iterator对象(25.1.1.2),其下一个方法迭代O的所有可枚举属性的String值键。Iterator对象必须继承%IteratorPrototype%(25.1.2)。没有指定枚举属性的机制和顺序,但必须符合下面[1]中指定的规则。
ES7 /
ES2016删除了[[Enumerate]]内部方法,而是使用了抽象操作EnumerateObjectProperties,但是就像[[Enumerate]]一样,它没有指定任何顺序。
也可以从查看此报价Object.keys
:
如果实现为for-in语句定义了特定的枚举顺序,则[…]
这意味着不需要实现来定义特定的枚举顺序。ECMAScript 2015语言规范的项目编辑Allen Wirfs-Brock在规范完成后发表的帖子中已确认了这一点。
这意味着不需要实现来定义特定的枚举顺序。ECMAScript 2015语言规范的项目编辑Allen Wirfs-Brock在规范完成后发表的帖子中已确认了这一点。
其他操作,如Object.getOwnPropertyNames,Object.getOwnPropertySymbols,Object.defineProperties
,并Reflect.ownKeys
做好后续普通物体下面的命令:
此行为在[[OwnPropertyKeys]]
内部方法中定义。但是某些奇异的对象对内部方法的定义略有不同。例如,代理的ownKeys
陷阱可能以任何顺序返回数组:
console.log(Reflect.ownKeys(new Proxy({}, {
ownKeys: () => ['3','1','2']
}))); // ['3','1','2'], the integer indices are not sorted!
[1]它下面说:
[[Enumerate]]必须获得目标对象自己的属性键, 就像 通过调用其[[OwnPropertyKeys]]内部方法一样。
并且[[OwnPropertyKeys]]的顺序是明确定义的。但是,不要让您感到困惑:“好像”仅表示“相同的属性”,而不是“相同的顺序”。
可以在EnumerableOwnNames中看到,它使用[[OwnPropertyKeys]]获取属性,然后对它们进行排序
如果调用[[Enumerate]]内部方法,则返回的顺序与Iterator产生的顺序相同。
如果要求[[Enumerate]]以与[[OwnPropertyKeys]]相同的顺序进行迭代,则无需重新排序。
问题内容: 我已经阅读了Java和C++之间的枚举差异问题?但是我还是很困惑。 我想以下返回相关的字符串: 据我所读,这应该是可能的。只是希望您对如何实现它有所了解。 问题答案: 简短答案 您需要一个构造函数,一个字段和一个吸气剂。 建设者 枚举类型可以具有构造函数,只要它们的访问级别为私有或默认(包私有)即可。除了枚举声明本身之外,您不能直接调用这些构造函数。与类相似,当定义不带参数的枚举常量时
问题内容: 如何枚举JavaScript对象的属性? 我实际上想列出所有已定义的变量及其值,但是我了解到定义一个变量实际上会创建window对象的属性。 问题答案: 很简单: 现在,您将无法以这种方式获取私有变量,因为它们不可用。 编辑:是正确的,除非您使用该方法,否则您将获得继承的属性- 但是,我不知道为什么任何熟悉面向对象编程的人都期望得到更少的东西!通常,提起此问题的人会受到道格拉斯·克罗克
问题内容: 我有一个界面-这是一个很好的版本示例: 如果我将枚举定义为静态,则此实现的执行方式有什么不同-即是否有任何效果: 问题答案: 不,没关系。但是,原因并不是因为它是接口内的成员声明,如Jon所说。真正的原因是根据语言规范( 8.9 ) 嵌套枚举类型是隐式静态的。可以将嵌套枚举类型显式声明为静态。 在以下示例中,static也没有任何区别(即使我们没有接口): 另一个带有嵌套 私有 枚
问题内容: 如果我创建这样的对象: 生成的对象会 总是 这样吗? 也就是说,属性的顺序是否与我添加它们的顺序相同? 问题答案: 自ES2015起,对象的迭代顺序遵循一组特定的规则,但不(始终)遵循插入顺序。简而言之,迭代顺序是字符串键的插入顺序和数字键的升序的组合: 使用数组或Map对象可能是实现此目的的更好方法。Map与密钥共享一些相似之处Object并保证密钥按插入顺序进行迭代,无一例外: M
问题内容: 在JavaScript中,我们有几种获取对象属性的方式,具体取决于我们想要获取的内容。 1),它返回对象的所有自己的,可枚举的属性,即ECMA5方法。 2)循环,返回对象的所有可枚举属性,无论它们是自己的属性还是从原型链继承。 3)返回对象本身的所有属性,无论是否可枚举。 我们还拥有诸如让我们检查属性是否继承或实际上属于该对象之类的方法,以及顾名思义,可以让我们检查属性是否可枚举的方法
问题内容: 如何将类属性声明为对象? 我试过了: 但这没有用。另外,为什么要那样做呢? 只实例化该对象并使用其成员不是更好吗? 问题答案: 从有关类属性的PHP手册(重点是我的): 类成员变量称为“属性”。您可能还会看到使用其他术语(例如“属性”或“字段”)来引用它们,但是出于参考目的,我们将使用“属性”。它们是使用关键字public,protected或private之一定义的,后跟普通变量声明