Javascript中的“for…in”循环是否按照声明的顺序遍历哈希表/元素?有没有浏览器是不按顺序执行的? 我希望使用的对象只声明一次,永远不会被修改。

假设我有:

var myObject = { A: "Hello", B: "World" };

我进一步将它们用于:

for (var item in myObject) alert(item + " : " + myObject[item]);

在大多数像样的浏览器中,“A:“Hello”总是出现在“B:“World”之前吗?


当前回答

来自ECMAScript语言规范,第12.6.4节(关于..在循环):

枚举属性的机制依赖于实现。枚举顺序由对象定义。

第4.3.3节(“对象”的定义):

它是一个无序的属性集合,每个属性包含一个基本值、对象或函数。存储在对象属性中的函数称为方法。

我猜这意味着您不能依赖于在JavaScript实现中以一致的顺序枚举的属性。(无论如何,依赖于特定于实现的语言细节都是糟糕的风格。)

如果你想定义你的订单,你需要实现一些定义它的东西,比如你在访问对象之前排序的键数组。

其他回答

一年后再碰这个……

现在已经是2012年了,主流浏览器仍然存在差异:

function lineate(obj){
    var arr = [], i;
    for (i in obj) arr.push([i,obj[i]].join(':'));
    console.log(arr);
}
var obj = { a:1, b:2, c:3, "123":'xyz' };
/* log1 */  lineate(obj);
obj.a = 4;
/* log2 */  lineate(obj);
delete obj.a;
obj.a = 4;
/* log3 */  lineate(obj);

Gist或测试在当前浏览器

Safari 5, Firefox 14

["a:1", "b:2", "c:3", "123:xyz"]
["a:4", "b:2", "c:3", "123:xyz"]
["b:2", "c:3", "123:xyz", "a:4"]

Chrome 21, Opera 12, Node 0.6, Firefox 27

["123:xyz", "a:1", "b:2", "c:3"]
["123:xyz", "a:4", "b:2", "c:3"]
["123:xyz", "b:2", "c:3", "a:4"]

IE9

[123:xyz,a:1,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 
[123:xyz,a:4,b:2,c:3] 

在IE6中,不保证顺序。

对象中for/in枚举的元素是没有设置DontEnum标志的属性。ECMAScript,又名Javascript,标准明确指出“对象是属性的无序集合”(参见http://www.mozilla.org/js/language/E262-3.pdf节8.6)。

假设所有Javascript实现都按照声明顺序枚举是不符合标准的(即不安全)。

迭代顺序也与删除属性有关,但在这种情况下仅针对IE。

var obj = {};
obj.a = 'a';
obj.b = 'b';
obj.c = 'c';

// IE allows the value to be deleted...
delete obj.b;

// ...but remembers the old position if it is added back later
obj.b = 'bb';
for (var p in obj) {
    alert(obj[p]); // in IE, will be a, bb, then c;
                   // not a, c, then bb as for FF/Chrome/Opera/Safari
}

如果http://code.google.com/p/v8/issues/detail?id=164上的讨论有任何指示的话,那么改变规范以修正迭代顺序的愿望似乎是开发人员中相当流行的愿望。

来自ECMAScript语言规范,第12.6.4节(关于..在循环):

枚举属性的机制依赖于实现。枚举顺序由对象定义。

第4.3.3节(“对象”的定义):

它是一个无序的属性集合,每个属性包含一个基本值、对象或函数。存储在对象属性中的函数称为方法。

我猜这意味着您不能依赖于在JavaScript实现中以一致的顺序枚举的属性。(无论如何,依赖于特定于实现的语言细节都是糟糕的风格。)

如果你想定义你的订单,你需要实现一些定义它的东西,比如你在访问对象之前排序的键数组。