{"/book":1,"/order":2,"deliver":3}
在我的应用程序的用户界面中,当我点击/预订时,我知道从地图上可以找到什么步骤。 有时我只想通过递增数字来进入下一步,但确保URL也会发生变化。
如何从一步到另一键进行反向映射。
我遇到了ECMAScript 5中介绍的Object.keys。 返回的键列表中的元素顺序是否始终相同?
["/book","/order","deliver"]
如果是,那为什么呢?字典是无序的吗?
答案 0 :(得分:1)
由实施决定。来自ES5 spec on Object.keys
:
如果实现为for-in语句定义了特定的枚举顺序,则必须在此算法的步骤5中使用相同的枚举顺序。
那里提到的“第5步”没有指定订单:
5.对于O的每个自己的可枚举属性,其名称为String ...
答案 1 :(得分:1)
ECMAScript 5.1 specification表示
当使用参数O调用keys函数时,执行以下步骤 采取:
- 如果Type(O)不是Object,则抛出TypeError异常。
- 设n为O
的自身可枚举属性的数量- 让数组成为创建新Object的结果,就好像通过表达式new Array(n),其中Array是标准内置 具有该名称的构造函数。
- 让索引为0。
- 对于名称String为P的O的每个自己的可枚举属性: (a)使用参数ToString(index)调用数组的[[DefineOwnProperty]]内部方法,PropertyDescriptor {[[Value]]:P, [[Writable]]:true,[[Enumerable]]:true,[[Configurable]]:true},和 假。 (b)增加指数1。
- 返回阵列。
醇>如果实现定义了枚举的特定顺序 for-in语句,必须在步骤5中使用相同的枚举顺序 这个算法。
Mozilla开发网络可以说明for-in loop:
for ... in循环以任意顺序迭代对象的属性(有关为什么不能依赖于迭代的看似有序性的原因,请参阅delete运算符,至少在跨浏览器设置中)。
delete operator的引用导致了这一点:
虽然ECMAScript使对象的迭代顺序依赖于实现,但似乎所有主流浏览器都支持基于最先添加的属性的迭代顺序(至少对于不在原型上的属性)。但是,对于Internet Explorer,当在属性上使用delete时,会导致一些令人困惑的行为,从而阻止其他浏览器将对象文字等简单对象用作有序关联数组。在资源管理器中,虽然属性值确实设置为未定义,但如果后来添加了一个具有相同名称的属性,则该属性将在其旧位置迭代 - 而不是在迭代序列的末尾,正如人们可能期望的那样删除了该属性,然后将其添加回来。
因此,如果要在跨浏览器环境中模拟有序关联数组,则必须使用两个单独的数组(一个用于键,另一个用于值),或者构建一个单属性数组对象等。
我认为从中得出的结论是,在单个浏览器中,订单将是任意的但是一致但如果您比较多个浏览器,那么这些浏览器的顺序可能会有所不同(特别是如果您要删除并重新添加属性)。
修改强>
如果您想根据相关值对键进行排序,那么您可以执行以下操作:
var map = { b: 2, a: 1, c: 3 };
var keys = Object.keys( map );
console.log( keys ); // [ 'b', 'a', 'c' ]
var sorted_keys = keys.slice(0); // sliced so that we can see the difference in order
sorted_keys.sort( function( a, b ){ return map[a] - map[b]; } );
console.log( sorted_keys ); // [ 'a', 'b', 'c' ]