从数据结构分析看:用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 相关文章推荐
jquery实现微博文字输入框 输入时显示输入字数 效果实现
Jul 12 Javascript
对 jQuery 中 data 方法的误解分析
Jun 18 Javascript
Javascript通过overflow控制列表闭合与展开的方法
May 15 Javascript
浏览器中url存储的JavaScript实现
Jul 07 Javascript
基于jQuery倾斜打开侧边栏菜单特效代码
Sep 15 Javascript
javascript的几种继承方法介绍
Mar 22 Javascript
基于jQuery实现仿微博发布框字数提示
Jul 27 Javascript
Ionic2开发环境搭建教程
Aug 20 Javascript
jquery加载单文件vue组件的方法
Jun 20 jQuery
微信小程序项目实践之主页tab选项实现
Jul 18 Javascript
JS实现checkbox互斥(单选)功能示例
May 04 Javascript
sortable+element 实现表格行拖拽的方法示例
Jun 07 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
php列出一个目录下的所有文件的代码
2012/10/09 PHP
Laravel 5框架学习之环境与配置
2015/04/08 PHP
PHP Cookei记录用户历史浏览信息的代码
2016/02/03 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
避免回车键导致的页面无意义刷新的解决方法
2011/04/12 Javascript
javascript 全选与全取消功能的实现代码
2012/12/23 Javascript
js点击文本框弹出可选择的checkbox复选框
2016/02/03 Javascript
Angular 中 select指令用法详解
2016/09/29 Javascript
Angular 2应用的8个主要构造块有哪些
2016/10/17 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
2017/02/28 Javascript
jQuery EasyUI Layout实现tabs标签的实例
2017/09/26 jQuery
Angular Renderer (渲染器)的具体使用
2018/05/03 Javascript
JavaScript的Object.defineProperty详解
2018/07/09 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
2019/06/24 Javascript
layui.tree组件的使用以及搜索节点功能的实现
2019/09/26 Javascript
uni-app 自定义底部导航栏的实现
2020/12/11 Javascript
python反编译学习之字节码详解
2019/05/19 Python
Python turtle绘画象棋棋盘
2019/08/21 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
2019/10/23 Python
python中设置超时跳过,超时退出的方式
2019/12/13 Python
Python模块 _winreg操作注册表
2020/02/05 Python
django 实现手动存储文件到model的FileField
2020/03/30 Python
Python使用re模块验证危险字符
2020/05/21 Python
详解anaconda安装步骤
2020/11/23 Python
Smashbox英国官网:美国知名彩妆品牌
2017/11/13 全球购物
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
小学班长竞选演讲稿
2014/04/24 职场文书
关爱留守儿童标语
2014/06/18 职场文书
银行贷款收入证明
2014/10/17 职场文书
企业党建工作总结2015
2015/05/26 职场文书
感恩教育主题班会
2015/08/12 职场文书
python爬虫selenium模块详解
2021/03/30 Python
解决Pytorch修改预训练模型时遇到key不匹配的情况
2021/06/05 Python
试了下Golang实现try catch的方法
2021/07/01 Golang
Win11如何修改dns?Win11修改dns图文教程
2022/01/18 数码科技
volatile保证可见性及重排序方法
2022/08/05 Java/Android