最近一个项目的开发中,初始化导航菜单的数据,后台给定的数据是 JavaScript 对象,其键是菜单的 id (数字),值是菜单对象。数据如下:
1 2 3 4 5 6 7 8 9 10 11 12 | var menuList = { '26' :{ 'name' : '新闻' , 'model' : 'list' }, '23' :{ 'name' : '娱乐' , 'model' : 'list' }, '25' :{ 'name' : '体育' , 'model' : 'list' }, '21' :{ 'name' : '读书' , 'model' : 'list' }, '24' :{ 'name' : '时尚' , 'model' : 'list' }, '22' :{ 'name' : '女性' , 'model' : 'list' } }; var info = document.getElementById( 'info' ); for (menu in menuList) { info.innerHTML += menu + " : " + menuList[menu][ 'name' ] + "<br/>" ; } |
在 IE6、IE7、IE8、Firefox、Safari(包括 iPhone)中,遍历得到的结果,和给定的一致:
1 2 3 4 5 6 | 26 : 新闻 23 : 娱乐 25 : 体育 21 : 读书 24 : 时尚 22 : 女性 |
而在 IE9、Chrome、Opera、Android 中,输出的顺序则是:
1 2 3 4 5 6 | 21 : 读书 22 : 女性 23 : 娱乐 24 : 时尚 25 : 体育 26 : 新闻 |
参考此文得知原因如下:
- 根据 ECMA-262(ECMAScript)第三版中描述,for-in 语句的属性遍历的顺序是由对象定义时属性的书写顺序决定的。
- 在现有最新的 ECMA-262(ECMAScript)第五版规范中,对 for-in 语句的遍历机制又做了调整,属性遍历的顺序是没有被规定的。
- 新版本中的属性遍历顺序说明与早期版本不同,这将导致遵循 ECMA-262 第三版规范内容实现的 JavaScript 解析引擎(如IE6 IE7 IE8 Firefox Safari 浏览器的 JavaScript 解析引擎,它们完成时间早于 ECMA-262 第五版规范发布时间)在处理 for-in 语句时,与遵循第五版规范实现的解析引擎,对属性的遍历顺序存在不一致的问题。