Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript中的排序属性已损坏_Javascript - Fatal编程技术网

Javascript中的排序属性已损坏

Javascript中的排序属性已损坏,javascript,Javascript,我需要遍历一个JavaScript对象,将其视为一个带有自定义键的数组。 我知道这是不完全支持的,因为属性没有内在的顺序,但由于我总是对属性重新排序,我发现这种方法简单可靠。。。直到现在 当键是数字或可以转换为数字的字符串时,就会出现问题 当我运行此代码时: var test1={4294966222:“A”,4294966333:“A”,4294966111:“A”}; var test2={4294968222:“A”,4294968333:“A”,4294968111:“A”}; 对于(

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

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

当我运行此代码时:

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
,执行以下操作:

  • 对于作为数组索引的O的每个自己的属性键p,按升序数字索引顺序,执行以下操作

    a。添加P作为键的最后一个元素

  • 对于作为字符串但不是数组索引的O的每个自己的属性键p,按照属性创建的时间升序,执行以下操作

    a。添加P作为键的最后一个元素

  • 升序数字顺序仅适用于作为数组标记的属性

    那么,“数组索引”是什么

    整数索引是一个字符串值属性键,它是一个规范的数字字符串(参见7.1.21),其数值为+0或正整数≤ 2^53 - 1. 数组索引是数值i在+0范围内的整数索引≤ 我<2^32-1

    因此,大于2^32的数值属性不是数组标记,因此按属性创建顺序迭代。但是,小于
    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
    )。所以,它们不是数组标记,所以它们是按属性创建顺序迭代的,而不是按升序数字顺序迭代的-这正是它们在小提琴中所做的,正如预期的那样。(见我的答案)