对于Microsoft IE,如果插入具有已删除键的元素且元素总数大于31,则JSON对象的顺序将相反。

迄今为止,此问题仅发生在IE中。 而且,在Chrome,Firefox,Safari和Opera中不会发生这种情况,该元素将按插入顺序插入。

通过在具有不同“计数”值的不同浏览器上运行以下测试代码,可以重现此问题。

<script>
    var temp = {};
    var count = 31;
    add = function(){
        for(var i=0; i<count;i++)
        {
            var id = "id:"+i;
            var c = {};
            c[id] = "value:"+i;
            console.log("push at " + i + " = " + id);
            _.extend(temp, c);
        }
    }
    display = function(){
        var i=0;
        $.each(temp,function(key, value){
            console.log("list at "+i+" = " + key);
            i++;
        });
    }
    deletion = function(){
        var i=0;
        $.each(temp,function(key, value){
            console.log("delete at " + i+ " = "+key);
            delete temp[key];
            i++;    
        });
    }
    add();
    display();
    deletion();
    add();
    display();
</script>

请注意,根据ECMA标准将元素推送到JSON对象时,排序并不重要。

===============>>#1 票数:2

首先,这不是JSON对象,而是JS对象。 JSON是一种序列化格式,用于传递包含编码数据的文本字符串。 JS中的对象是实际对象,而不是一个字符串表示形式。

其次,JS对象(以及发生的JSON对象)被明确定义为键-值对的无序集合 您可以遍历它们,但是您不能依赖于以任何特定顺序获取元素。

幼稚的JS实现只需将每个新的键值对添加到列表的末尾。 但这意味着每当您访问特定的密钥时,都必须搜索整个列表以找到它。 显然,这对于具有许多键的对象将变得非常低效。 因此,相反,经过优化的JS引擎会做得更聪明-它可以按字母顺序存储密钥,以便可以对密钥执行二进制搜索; 或更可能的是,它将使用某种哈希函数并以此排序,以便二进制搜索更有可能达到最佳效率。

对于小型对象,存在另一个与效率有关的问题:内存使用情况。 理想情况下,一个对象将占据单个连续的内存块,并在任一侧被其他对象或数据围绕。 当您添加更多键或更长的值时,对象的内存需要增加,并且将整个对象移动到更大的空间将很慢,并且在旧位置留有空隙,因此,引擎又需要做一些更聪明的事情。 这可能包括预先分配额外的空间以增长到该空间,以及重复使用已删除项目腾出的空间(同样,以使引擎效率最大化的顺序)。

所有这些都将根据特定情况在引擎内部进行动态调整,其中包括键值对的数量和大小,甚至包括对象的用途。 因此,在重复删除和插入的影响下,超出一定大小并不奇怪,现代的浏览器选择了以相反顺序结束的策略。

最重要的是不要对对象中键的顺序做任何假设 就您的代码而言,它们实际上是随机排列的。

  ask by Marcel David translate from so

未解决问题?本站智能推荐: