Javascript中的排序属性已损坏
我需要遍历一个JavaScript对象,将其视为一个带有自定义键的数组。 我知道这是不完全支持的,因为属性没有内在的顺序,但由于我总是对属性重新排序,我发现这种方法简单可靠。。。直到现在 当键是数字或可以转换为数字的字符串时,就会出现问题 当我运行此代码时:Javascript中的排序属性已损坏,javascript,Javascript,我需要遍历一个JavaScript对象,将其视为一个带有自定义键的数组。 我知道这是不完全支持的,因为属性没有内在的顺序,但由于我总是对属性重新排序,我发现这种方法简单可靠。。。直到现在 当键是数字或可以转换为数字的字符串时,就会出现问题 当我运行此代码时: var test1={4294966222:“A”,4294966333:“A”,4294966111:“A”}; var test2={4294968222:“A”,4294968333:“A”,4294968111:“A”}; 对于(
var test1={4294966222:“A”,4294966333:“A”,4294966111:“A”};
var test2={4294968222:“A”,4294968333:“A”,4294968111:“A”};
对于(test1中的var k){console.log(k);}
console.log(“--”);
对于(test2中的var k){console.log(k);}
这与遍历对象键的方式有关
根据ES6规范,其应为:
9.1.12 [[OwnPropertyKeys]] ( )
When the [[OwnPropertyKeys]] internal method of O is called 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
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 property creation order
Add P as the last element of keys.
For each own property key P of O that is a Symbol, in property creation order
Add P as the last element of keys.
Return keys.
这意味着如果一个键的值在转换为无符号53位数字时保持不变
在后面,它被视为一个整数索引,以升序数字顺序进行排序
如果失败,它将被视为字符串键,按添加方式排序
对该对象
这里的问题是,所有主要的浏览器还没有遵循这个规范
并使用数组索引,该索引最多为正数。
因此,任何超过该限制的内容实际上都是字符串键。这是意料之中的。根据,对属性进行迭代的方法,OrdinaryOwnPropertyKeys
,执行以下操作:
2^32
的数值属性是数组标记,并按升序数字顺序迭代
例如:
1
:数组索引将以数字形式迭代
10
:数组索引将以数字形式迭代
4294968111
:大于2**32
,将在数组标记完成后按属性创建顺序迭代
999999999999
:大于2**32
,将在数组标记完成后按属性创建顺序迭代
另外,请记住,与流行的观点相反,属性迭代顺序也是由规范保证的,这要归功于第4阶段。我猜散列码是如何计算的,但它不是你问题的真正答案。我不认为它在真正的口语意义上被打破了,它们不保证值将按顺序迭代,因为它可以任意运行,您可以检查“注意:for…in不应用于迭代索引顺序很重要的数组。”它们只保证迭代集合中的每个元素。像forEach这样的东西确实考虑到了顺序,通过以升序遍历记录项,您可以通过记录
test1
和test2
直接看到问题。我认为“问题”来自规范的V8实现中的密钥缓存。更重要的是,在2^32以下,您的属性名称的顺序恰好与内部属性引用相似。您可以也不应该依赖对象属性的顺序,因为根据定义,它们不是有序的,并且可以包含对象固有的属性。始终将对象投射/映射到数组中,对数组进行排序,如果顺序很重要,则循环遍历该数组。@Mr.Toxy这是因为那些属性4294968333
和4294968111
大于2**32
(即4294967296
)。所以,它们不是数组标记,所以它们是按属性创建顺序迭代的,而不是按升序数字顺序迭代的-这正是它们在小提琴中所做的,正如预期的那样。(见我的答案)