从数据结构分析看:用for each...in 比 for...in 要快些


Posted in Javascript onApril 17, 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里储存存了keys的列表,也把每个values值作为链表关联起来。每当有值添加或删除,就更新其链接关系。

当for each...in遍历时,只需从第一个节点往后迭代即可,无需任何Hash计算。

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

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

Javascript 相关文章推荐
js获取当前select 元素值的代码
Apr 19 Javascript
使用js判断当前时区TimeZone是否是夏令时
Feb 23 Javascript
把Node.js程序加入服务实现随机启动
Jun 25 Javascript
Bootstrap3学习笔记(三)之表格
May 20 Javascript
js/jq仿window文件夹框选操作插件
Mar 08 Javascript
Vue中的v-cloak使用解读
Mar 27 Javascript
微信小程序 地图map实例详解
Jun 07 Javascript
js模块加载方式浅析
Aug 12 Javascript
详解redux异步操作实践
Aug 15 Javascript
通过JS深度判断两个对象字段相同
Jun 14 Javascript
ES5新增数组的实现方法
May 12 Javascript
typescript编写微信小程序创建项目的方法
Jan 29 Javascript
关于eval 与new Function 到底该选哪个?
Apr 17 #Javascript
js实现在页面上弹出蒙板技巧简单实用
Apr 16 #Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
Apr 16 #Javascript
拖动table标题实现改变td的大小(css+js代码)
Apr 16 #Javascript
获取offsetTop和offsetLeft值的js代码(兼容)
Apr 16 #Javascript
jquery表格内容筛选实现思路及代码
Apr 16 #Javascript
js实现图片轮换效果代码
Apr 16 #Javascript
You might like
javascript不同页面传值的改进版
2008/09/30 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
javascript面向对象特性代码实例
2014/06/12 Javascript
jquery实现图片按比例缩放示例
2014/07/01 Javascript
使用JavaScript进行进制转换将字符串转换为十进制
2014/09/21 Javascript
JavaScript中自定义事件用法分析
2014/12/23 Javascript
完美实现仿QQ空间评论回复特效
2015/05/06 Javascript
React.js入门实例教程之创建hello world 的5种方式
2016/05/11 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
利用JQuery实现datatables插件的增加和删除行功能
2017/01/06 Javascript
vue2.0中click点击当前li实现动态切换class
2017/06/21 Javascript
JS实现的简单折叠展开动画效果示例
2018/04/28 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
如何使用CSS3+JQuery实现悬浮墙式菜单
2019/06/18 jQuery
微信小程序 云开发模糊查询实现解析
2019/09/02 Javascript
小程序自定义弹框效果
2020/11/16 Javascript
Python中的多重装饰器
2015/04/11 Python
python查看zip包中文件及大小的方法
2015/07/09 Python
python实现决策树C4.5算法详解(在ID3基础上改进)
2017/05/31 Python
Python数据结构与算法之字典树实现方法示例
2017/12/13 Python
python添加模块搜索路径和包的导入方法
2019/01/19 Python
python 使用装饰器并记录log的示例代码
2019/07/12 Python
详解centos7+django+python3+mysql+阿里云部署项目全流程
2019/11/15 Python
Python Tensor FLow简单使用方法实例详解
2020/01/14 Python
详解python datetime模块
2020/08/17 Python
网站编辑求职信
2013/10/17 职场文书
汽车驾驶求职信
2013/10/25 职场文书
会计电算化专业求职信
2014/06/10 职场文书
基层党建工作宣传标语
2014/06/24 职场文书
领导班子自我剖析材料
2014/08/16 职场文书
出国签证在职证明
2014/09/20 职场文书
群众路线党员自我评议范文2014
2014/09/24 职场文书
公司离职证明标准范本
2014/10/05 职场文书
五年级上册复习计划
2015/01/19 职场文书
生产现场禁烟通知
2015/04/23 职场文书
MySQL系列之四 SQL语法
2021/07/02 MySQL