从数据结构的角度分析 for each in 比 for in 快的多


Posted in Javascript onJuly 07, 2013

之前听说火狐的JS引擎支持for each in的语法,例如下述的代码:

var arr = [10,20,30,40,50];
for each(var k in arr)
console.log(k);

即可直接遍历出arr数组的内容。

由于只有FireFox才支持,所以几乎所有的JS代码都不用这一特征。

不过在ActionScript里天生就支持for each的语法,不论Array还是Vector,还是Dictionary,只要是可枚举的对象都可以for in和for each in。

之前并没有感觉有太大的差异,为了懒得敲一个each单词,一直用熟悉的for in来遍历。

不过今天仔细琢磨了会,从数据结构的角度分析了下,觉得for in和for each in效率上有着本质的区别,无论是JS还是AS。

原因很简单:Array不是真正意义上的数组!

何为真正意义的数组?当然就是传统语言里type[]定义的数据类型,所有元素都是连续保存的。

“Array”虽然也是数组的意思,但熟悉JS的都知道,它其实是个非线性的伪数组,下标可以是任意数字。写入arr[1000000]并非真正申请容纳一百万个元素的空间,而是把1000000转换成相应的哈希值,对应到很小一块储存空间里,从而节省了大量内存。

例如有如下数组:

var arr = [];
  arr[10] = 1000;
  arr[20] = 2000;
  arr[30] = 5000;
  arr[40] = 8000;
  arr[200] = 9000;

用for...in遍历Array,是个很累赘的过程:

从数据结构的角度分析 for each in 比 for in 快的多

遍历时每次访问arr[k],都要进行一次Hash(k)计算,根据散列表的容量取模,如果存在冲突还得寻找最终的值结果。

如果支持for each...in的语法,其内部的数据结构就决定了会快很多:

从数据结构的角度分析 for each in 比 for in 快的多

Array里直接把每个values作为节点,通过链表关联起来维护。每当有值添加或删除,就更新其链接关系。
当for each...in遍历时,只需从第一个节点往后迭代即可,无需任何Hash计算。

当然,对于AS3里Vector这样的线性数组来说,两者相差不大;同理,HTML5里支持二进制的数组ArrayBuffer也是如此。不过从理论上来看,即使arr是个连续的线性数组,for each in还是要快一点:

for...in遍历时,每次访问arr[k]都要进行下标越界检查;而for each in则根据内部链表,直接从底层反馈出迭代变量,节省了越界检查的过程。

Javascript 相关文章推荐
MooTools 1.2介绍
Sep 14 Javascript
JSON辅助格式化处理方法
Mar 26 Javascript
node.js读取文件到字符串的方法
Jun 29 Javascript
原生js代码实现图片放大境效果
Oct 30 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
Mar 14 Javascript
详解react-webpack2-热模块替换[HMR]
Aug 03 Javascript
JavaScript实现的搜索及高亮显示功能示例
Aug 14 Javascript
Vue使用NPM方式搭建项目
Oct 25 Javascript
React-redux实现小案例(todolist)的过程
Sep 29 Javascript
Windows下安装 node 的版本控制工具 nvm
Feb 06 Javascript
浅谈JavaScript 声明提升
Sep 14 Javascript
在JavaScript中查找字符串中最长单词的三种方法(推荐)
Jan 18 Javascript
JavaScript 上万关键字瞬间匹配实现代码
Jul 07 #Javascript
20行代码实现的一个CSS覆盖率测试脚本
Jul 07 #Javascript
在JavaScript里嵌入大量字符串常量的实现方法
Jul 07 #Javascript
JQuery表格内容过滤的实现方法
Jul 05 #Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
Jul 05 #Javascript
Javascript实现动态菜单添加的实例代码
Jul 05 #Javascript
javascript实现跳转菜单的具体方法
Jul 05 #Javascript
You might like
PHP简洁函数小结
2011/08/12 PHP
php处理restful请求的路由类分享
2014/02/27 PHP
PHP CURL 多线程操作代码实例
2015/05/13 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
IE不出现Flash激活框的小发现的js实现方法
2007/09/07 Javascript
IE8下关于querySelectorAll()的问题
2010/05/13 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
JS去除数组重复值的五种不同方法
2013/09/06 Javascript
JS中字符串trim()使用示例
2015/05/26 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
vue.js声明式渲染和条件与循环基础知识
2017/07/31 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
2017/09/13 Javascript
jquery点击回车键实现登录效果并默认焦点的方法
2018/03/09 jQuery
详解vue通过NGINX部署在子目录或者二级目录实践
2018/09/03 Javascript
VUE+elementui组件在table-cell单元格中绘制微型echarts图
2020/04/20 Javascript
OpenLayers3实现对地图的基本操作
2020/09/28 Javascript
python条件和循环的使用方法
2013/11/01 Python
详细介绍Python的鸭子类型
2016/09/12 Python
python与php实现分割文件代码
2017/03/06 Python
[原创]使用豆瓣提供的国内pypi源
2017/07/02 Python
利用python对Excel中的特定数据提取并写入新表的方法
2018/06/14 Python
使用Selenium破解新浪微博的四宫格验证码
2018/10/19 Python
python selenium爬取斗鱼所有直播房间信息过程详解
2019/08/09 Python
Python学习笔记之Zip和Enumerate用法实例分析
2019/08/14 Python
Html5百叶窗效果的示例代码
2017/12/11 HTML / CSS
瑞典领先的汽车零部件网上零售商:bildelaronline24.se
2017/01/12 全球购物
Lulu Guinness露露·吉尼斯官网:红唇包
2019/02/03 全球购物
Java基础类库面试题
2013/09/04 面试题
职工趣味运动会方案
2014/02/10 职场文书
刚毕业大学生自荐信范文
2014/02/20 职场文书
教师师德承诺书
2014/03/26 职场文书
2015元旦晚会主持人开场白+结束语
2014/12/14 职场文书
2016年植树节红领巾广播稿
2015/12/17 职场文书
详解如何修改nginx的默认端口
2021/03/31 Servers
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript