Javascript 为什么Microsoft IE会更改对象的顺序';插入/删除时的s键?

Javascript 为什么Microsoft IE会更改对象的顺序';插入/删除时的s键?,javascript,internet-explorer,Javascript,Internet Explorer,对于Microsoft IE,如果插入具有已删除键的元素且元素总数大于31,则JSON对象的顺序将颠倒 到目前为止,这个问题只发生在IE中。 而且,在Chrome、Firefox、Safari和Opera中不会出现这种情况,元素按插入顺序插入 通过在不同的浏览器上以不同的“计数”值运行下面的测试代码,可以重现此问题 var temp={}; var计数=31; add=函数(){ 对于(var i=0;i首先,这不是一个JSON对象,而是一个JS对象。JSON是一种序列化格式,用于传递包含编码

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

到目前为止,这个问题只发生在IE中。 而且,在Chrome、Firefox、Safari和Opera中不会出现这种情况,元素按插入顺序插入

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


var temp={};
var计数=31;
add=函数(){

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

其次,JS对象(碰巧还有JSON对象)被显式定义为无序的键值对集。您可以对它们进行迭代,但不能依赖于以任何特定顺序获取元素

简单的JS实现只需将每个新的键值对添加到列表的末尾。但这意味着,无论何时访问某个特定的键,都必须搜索整个列表才能找到它;显然,对于具有大量键的对象,这将非常低效。因此,经过优化的JS引擎将做一些更聪明的事情——它可能存储密钥按字母顺序排列,因此它可以对密钥执行二进制搜索;或者更可能的是,它将使用一些哈希函数并按此进行排序,以便二进制搜索更有可能达到最佳效率

对于小型对象,有一个不同的效率问题:内存使用。理想情况下,一个对象会占用一个连续的内存块,两边都被其他对象或数据包围。当您添加更多的键或更长的值时,对象的内存需要增长,而将整个对象移动到更大的空间会很慢,并留下一个新的内存因此,引擎需要做一些更聪明的事情。这可能包括预先分配额外的空间来扩展,以及重用被删除的项目腾出的空间(同样,这样的顺序可以最大限度地提高引擎的效率)

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


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

您的问题是什么?您的代码中没有JSON,JavaScript对象顺序是由实现定义的。ECMA标准中没有要求它工作k实现之间的方式相同。JSON对象是在运行时构建的,如代码所示。也许,我应该称它为“[object object]”。不,仍然没有JSON。JSON是一种将对象存储为字符串的方式;您在上面的代码中没有使用它。您所拥有的只是“一个对象”。也许,你是对的,我对浏览器的实现没有深入的了解。但是,为什么IE在31元素之后会反转呢?@MarcelDavid:谁知道呢……也许是一些优化,其中小对象使用不同于大对象的内部数据结构,当它们更改结构时,它们会反向复制这些项以供使用性能原因。很有趣…当我使用>999个对象元素时,我可以从其他浏览器获得e隐式排序关系,但不能从IE获得。感谢您将此信息共享给我。
<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>