1. 属性列表
Object.keys
规定了,对象的key被枚举的顺序,
它会调用EnumerableOwnProperties ( O, kind )来计算所有可枚举的属性,
而EnumerableOwnProperties ( O, kind )又调用了OrdinaryOwnPropertyKeys ( O )得到对象所有属性的列表。
19.1.2.16 Object.keys ( O )
When the keys function is called with argument O, the following steps are taken:
- Let obj be ? ToObject(O).
- Let nameList be ? EnumerableOwnProperties(obj, "key").
- Return CreateArrayFromList(nameList).
7.3.21 EnumerableOwnProperties ( O, kind )
When the abstract operation EnumerableOwnProperties is called with Object O and String kind the following steps are taken:
- Assert: Type(O) is Object.
- Let ownKeys be ? O.[[OwnPropertyKeys]]().
- Let properties be a new empty List.
- For each element key of ownKeys in List order, do
4.1 If Type(key) is String, then
4.1.1 Let desc be ? O.[[GetOwnProperty]](key).
4.1.2 If desc is not undefined and desc.[[Enumerable]] is true, then
4.1.2.1 If kind is "key", append key to properties.
4.1.2.2 Else,
4.1.2.2.1 Let value be ? Get(O, key).
4.1.2.2.2 If kind is "value", append value to properties.
4.1.2.2.3 Else,
4.1.2.2.3.1 Assert: kind is "key+value".
4.1.2.2.3.2 Let entry be CreateArrayFromList(« key, value »).
4.1.2.2.3.3 Append entry to properties.- Order the elements of properties so they are in the same relative order as would be produced by the Iterator that would be returned if the EnumerateObjectProperties internal method were invoked with O.
- Return properties.
9.1.11 [[OwnPropertyKeys]] ( )
When the [[OwnPropertyKeys]] internal method of O is called, the following steps are taken:
- Return ! OrdinaryOwnPropertyKeys(O).
9.1.11.1 OrdinaryOwnPropertyKeys ( O )
When the abstract operation OrdinaryOwnPropertyKeys is called with Object O, the following steps are taken:
- Let keys be a new empty List.
- For each own property key P of O that is an integer index, in ascending numeric index order, do
2.1 Add P as the last element of keys.- For each own property key P of O that is a String but is not an integer index, in ascending chronological order of property creation, do
3.1 Add P as the last element of keys.- For each own property key P of O that is a Symbol, in ascending chronological order of property creation, do
4.1 Add P as the last element of keys.- Return keys.
OrdinaryOwnPropertyKeys ( O )对于不同类型的属性,会按不同的顺序放到属性列表中,
(1)先处理类型为数值的属性,从小到大放到属性列表中,
(2)再处理类型为字符串的属性,按该属性的创建顺序,放到属性列表中,
(3)最后处理类型为Symbol
的属性,按创建顺序,放到属性列表中。
注:
Object.keys
是ES 5(ECMAScript 2009)引入的特性,
经历了ES 5.1(ECMAScript 2011),返回的属性列表都是与具体实现相关的。
后来,在ES 6(ECMAScript 2015)中规定了上述枚举顺序,
然后到ES 7(ECMAScript 2016),ES 8(ECMAScript 2017),沿用至今。
2. 例子
x = {b:20, 3:2, [Symbol('A')]:2, a:100, 2:1};
> Object {2: 1, 3: 2, b: 20, a: 100, Symbol(A): 2}
Object.keys(x);
> ["2", "3", "b", "a"]
Chrome控制会调用OrdinaryOwnPropertyKeys ( O )显示出对象的所有属性,
而Object.keys
只会显示对象的可枚举属性。
此外,在控制台上交互式的展开对象的属性,则只能看到对象的可枚举属性。
↓ Object {2: 1, 3: 2, b: 20, a: 100, Symbol(A): 2}
2: 1
3: 2
a: 100
b: 20
Symbol(A): 2
__proto__: Object