cha*_*rit 196 javascript for-loop
Javascript中的"for ... in"循环是否按照声明的顺序循环遍历hashtables/elements?是否有一个浏览器没有按顺序执行?
我想要使用的对象将被声明一次,永远不会被修改.
假设我有:
var myObject = { A: "Hello", B: "World" };
Run Code Online (Sandbox Code Playgroud)
我进一步使用它们:
for (var item in myObject) alert(item + " : " + myObject[item]);
Run Code Online (Sandbox Code Playgroud)
在大多数体面的浏览器中,我可以期待'A:'你好''总是先来'B:'世界"吗?
Bor*_*gar 206
目前,所有主流浏览器都按照定义它们的顺序循环对象的属性.除了几个案例外,Chrome也可以做到这一点.[...] ECMAScript规范明确未明确定义此行为.在ECMA-262第12.6.4节中:
枚举属性的机制......依赖于实现.
但是,规范与实现完全不同.ECMAScript的所有现代实现都按照定义它们的顺序迭代对象属性.因此,Chrome团队认为这是一个错误,并将修复它.
所有浏览器都遵循定义顺序,Chrome和Opera 除外,它们适用于每个非数字属性名称.在这两个浏览器中,属性在第一个非数字属性之前按顺序拉出(这与它们如何实现数组有关).订单也是一样的Object.keys.
这个例子应该清楚说明发生了什么:
var obj = {
"first":"first",
"2":"2",
"34":"34",
"1":"1",
"second":"second"
};
for (var i in obj) { console.log(i); };
// Order listed:
// "1"
// "2"
// "34"
// "first"
// "second"
Run Code Online (Sandbox Code Playgroud)
这方面的技术性不如在任何时候可能发生变化的事实重要.不要依赖这样的事情.
简而言之:如果订单对您很重要,请使用数组.
dvd*_*rgn 54
一年之后就把这个搞得一团糟......
它是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);
Run Code Online (Sandbox Code Playgroud)
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"]
Run Code Online (Sandbox Code Playgroud)
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"]
Run Code Online (Sandbox Code Playgroud)
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]
Run Code Online (Sandbox Code Playgroud)
Tom*_*lak 26
从ECMAScript语言规范,第12.6.4节(在for .. in循环中):
枚举属性的机制取决于实现.枚举的顺序由对象定义.
第4.3.3节("对象"的定义):
它是一个无序的属性集合,每个属性都包含一个原始值,对象或函数.存储在对象属性中的函数称为方法.
我想这意味着你不能依赖于JavaScript实现中以一致顺序枚举的属性.(依靠语言的特定于实现的细节,无论如何都是糟糕的风格.)
如果您希望定义订单,则需要实现定义它的内容,例如在使用它访问对象之前排序的键数组.
Ada*_*ght 10
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
}
Run Code Online (Sandbox Code Playgroud)
如果http://code.google.com/p/v8/issues/detail?id=164上的讨论有任何迹象,那么更改规范以修复迭代顺序的愿望似乎是开发人员的一个普遍愿望。
| 归档时间: |
|
| 查看次数: |
86454 次 |
| 最近记录: |