进阶知识
Object.keys 能保证返回的对象属性的顺序?
简单回复: 不能。ECMA 规范是,先返回正整数属性,按值增序排序;再返回字符串或 Symbol,按属性创建的顺序,可保证顺序。但浏览器实现不一定都遵循规范,所以,不能信任 Object.keys() 的顺序。
const symbol1 = Symbol('symbol1')
const symbol2 = Symbol('symbol2')
const obj = {
'd': 'd',
symbol1: 'symbol1',
'a': 'a',
'c': 'c',
'b': 'd',
'1': 1,
'3.1': 3.1,
'2': 2,
symbol2: 'symbol2'
}
Object.keys(obj)
// ['1', '2', 'd', 'symbol1', 'a', 'c', 'b', '3.1', 'symbol2']
Object.keys():返回的数组顺序和与 for...in 循环提供的顺序相同。——MDN-Object.keys()
for...in:与最新的ECMAScript 规范一样,遍历顺序是明确定义且实现一致的—— 在原型链的每个组合中,首先按值升序遍历所有非负整数键(可以作为数组索引的键),然后按属性创建的升序时间顺序遍历其他字符串键。 ——MDN-for...in
Object.keys(O):
- O 转换为 Object;
- 获取属性列表:EnumerableOwnProperties(obj, key) -> O.[[OwnPropertyKeys]] -> OrdinaryOwnPropertyKeys(O);
- 将属性列表转换为 Array,并返回。
OrdinaryOwnPropertyKeys ( O ):
The abstract operation OrdinaryOwnPropertyKeys takes argument O (an Object) and returns a List of property keys. It performs the following steps when called:
- Let keys be a new empty List.
- For each own property key P of O such that P is an array index, in ascending numeric index order, do a. a. Append P to keys.
- For each own property key P of O such that P is a String and P is not an array index, in ascending chronological order of property creation, do a. a. Append P to keys.
- For each own property key P of O such that P is a Symbol, in ascending chronological order of property creation, do a. a. Append P to keys.
- Return keys.