Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

JavaScript中for-in的细节问题

  由于for-in的语法效率并不高,所以平时使用的情况也只是遍历对象的属性而已,所以对于这个语法就没有太深入的研究。翻了下ECMA262,发现里面并没有对很多具体的东西做定义。甚至对数据的存储方式也没有做定义,所以直接涉及存储的东西都是未定义行为。
  ECMA262第3版的8.6章的第一句是 An Object is an unordered collection of properties.   到了5.1版,同样是8.6章就变成了 An Object is a collection of properties.   也就是说,对象中保存的数据并不强调无序。collection只是表示集合,并不表示内容无序,更不表示内容排序随机。不过无论是第三版还是第五版,它们都没有涉入数据存储方式的定义。而for-in这个语法是从一个不做排序的数据中枚举的,而不做排序的数据存储顺序就和实现方法有关。幸好目前所有的JavaScript引擎对核心的存储方式一直没有改变(对于ECMA的定义目前也没有比HashTable更好的存储模式了)。所以,一般情况下,各种JS引擎下的行为都是相同的。
var i,o={y:0,x:1,z:2};
for(i in o)console.log(i);

  这就是没有排序结果,先入先出的枚举出数据。但是如果key是数字呢? var i,o={2:2,1:1,3:3};
for(i in o)console.log(i);

  虽然在各浏览器上输出的结果相同(IE6没测试,估计会是213),但是在微软的WSH上运行就会输出这样的结果。

  看吧,这货是213= =。这才是没有排序的结果。浏览器上也许是因为遍历数组的需求对它做了特殊的排序。
  除了遍历时的顺序问题,还有一个遍历过程中操作对象的问题。在ECMA中的描述是无法确定,其实那只是在说“在不确定的引擎下结果是不确定的”。在同一个引擎中,结果是可以确定的。我们当然知道自己的代码需要运行在什么引擎上,对于Web开发者而已引擎也就那么几个,完全可以确定。而且由于现代JavaScript引擎的实现方式都大同小异,只是优化的方向不同而已。所以在现代浏览器中,这并没有什么差异。所以对于Web的终端开发者而言“这真是极好的!”。
var i,o={x:1,y:2,z:3};
for(i in o){
  if(i=="x")o["w"]=4;
  console.log(i);
};

  只有IE8-上才会把for-in过程中添加的东西枚举出来,IE9+就与其它现代浏览器的结果相同了。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^