javascript - Javascript 中的排序属性已损坏

标签 javascript

我需要循环遍历一个 JavaScript 对象,将其视为具有自定义键的数组。 我知道这并没有得到完全支持,因为属性没有内在顺序,但由于我总是对属性重新排序,所以我发现这种方法简单可靠......直到现在。

当键是数字或可以转换为数字的字符串时,就会出现问题。

当我运行此代码时:

var test1 = {4294966222:"A",4294966333:"A",4294966111:"A"};
var test2 = {4294968222:"A",4294968333:"A",4294968111:"A"};
        
for (var k in test1) {console.log(k);}
console.log("---");
for (var k in test2) {console.log(k);}

输出是:

4294966111
4294966222
4294966333
---
4294968222
4294968333
4294968111

这意味着:

  • (test1)如果键小于 2^32 (4,294,967,296),它们会自动重新排序,最小的在前
  • (test2)如果键大于 2^32,则不会重新排序。

问题是:为什么会发生这种情况?

由于我测试的所有浏览器(Google Chrome 79.0、Mozilla Firefox 71.0、Microsoft Edge 44.18362、Internet Explorer 11.535)都同意此输出,因此必须有一些官方规范。

更新

在发现这是一个阈值问题之前,我测试了很多数字。我发现奇怪的是序列 2,3,1 的行为与以相同方式排序的三个时间戳不同。

最佳答案

这是预期的。根据 specification ,迭代属性的方法 OrdinaryOwnPropertyKeys 的作用是:

  1. For each own property key P of O that is an array index, in ascending numeric index order, do

    a. Add P as the last element of keys.

  2. For each own property key P of O that is a String but is not an array index, in ascending chronological order of property creation, do

    a. Add P as the last element of keys.

升序数字顺序适用于作为数组索引的属性。

那么,什么是“数组索引”? Look it up: :

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.21) and whose numeric value is either +0 or a positive integer ≤ 2^53 - 1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 2^32 - 1.

因此,大于 2^32 的数字属性不是数组索引,因此按照属性创建的顺序进行迭代。但是,小于 2^32 的数字属性是数组索引,并按升序数字顺序迭代。

例如:

1:数组索引,将按数字进行迭代

10:数组索引,将按数字进行迭代

4294968111:大于2 ** 32,将在数组索引完成后按属性创建顺序迭代

9999999999999:大于2 ** 32,将在数组索引完成后按属性创建顺序迭代

此外,请记住,与普遍的看法相反,属性迭代顺序也由规范保证,这要归功于 for-in iteration proposal这是第 4 阶段。

关于javascript - Javascript 中的排序属性已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59407858/

相关文章:

Javascript 可以在本地运行,但不能在带有 NiceEdit 的服务器上运行

javascript - 检测元素外部的点击,检查复选框是否被选中,并触发点击

java - 执行ajax时出现问题

javascript - 将 MongoDB 查询结果转换为 JSONArray

javascript - 结合两个下拉菜单来确定提交按钮链接

javascript - 在没有控件的情况下从谷歌地图打印 map

javascript - 从网格中读取数据

javascript - Mongoose find()不返回结果

javascript - 脚本导致 “Refused to execute inline script: Either the ' unsafe-inline' 关键字、哈希...或随机数需要启用内联执行”

javascript - 足球赛程javascript算法