猜猜以下内容的结果
var obj = {
city: "Beijing",
12: 12,
7: 7,
0: 0,
"-2": -2,
"age": 15,
"-3.5": -3.5,
7.7: 7.7,
_: "___",
online: true,
3: 3,
"23": "23",
"44": 44
}
for(key in obj){
console.log(key)
}
-
chrome
-
safari
-
firefox
-
IE
标准
-
根据 ECMA-262(ECMAScript)第三版中描述,for-in 语句的属性遍历的顺序是由对象定义时属性的书写顺序决定的。ECMA-262 3rd Edition【参考12.6.4 The for-in Statement。】
-
ECMA-262(ECMAScript)第五版规范中,对 for-in 语句的遍历机制又做了调整,属性遍历的顺序是没有被规定的。ECMA-262 5rd Edition 【参考13.7.5 The for‑in and for‑of Statements】
各大浏览器的行为
-
Chrome、 sarari、 firebox、 Opera 中使用 for-in 语句遍历对象属性时会遵循一个规律,它们会先提取所有 key 的 parseFloat 值为非负整数的属性, 然后根据数字顺序对属性排序首先遍历出来,然后按照对象定义的顺序遍历余下的所有属性。order is preserved with the major exception of keys like “7” that parse as integers and are handled differently by Chrome/V8
-
其它浏览器则完全按照对象定义的顺序遍历属性。
Chrome等现代浏览器较新版本 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范(看到11年stackoverflow上的讨论)。因此,使用 for-in 语句遍历对象属性时遍历书序并非属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。
有顺序的遍历
4.3.3 Object An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.
for-in、object.keys(objectX).map 语句无法保证对象的遍历顺序,应尽量避免编写依赖对象属性顺序的代码。
- 使用数组
- 使用es6 的Map类型:
A Map iterates its elements in insertion order, whereas iteration order is not specified for Objects.
譬如之前的例子:
var myMap = new Map();
myMap.set("city", "Beijing");
myMap.set(12, 12);
myMap.set(7, 7);
myMap.set(0, 0);
myMap.set("-2", -2);
myMap.set("age", 15);
myMap.set("-3.5", -3.5);
myMap.set(7.7, 7.7);
myMap.set("_", "___");
myMap.set("online", true);
myMap.set(3, 3);
myMap.set("23", "23");
myMap.set("44", 44);
//不支持for in 遍历
for (var [key, value] of myMap) {
console.log(key + ' = ' + value);
}