从数据结构分析看:用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 浮动广告实现代码
Dec 25 Javascript
下拉列表select 由左边框移动到右边示例
Dec 04 Javascript
js判断设备是否为PC并调整图片大小
Feb 12 Javascript
jQuery避免$符和其他JS库冲突的方法对比
Feb 20 Javascript
jQuery中get和post方法传值测试及注意事项
Aug 08 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
Sep 03 Javascript
JavaScript实现瀑布流布局
Jun 28 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
Dec 06 Javascript
jquery实现手机端单店铺购物车结算删除功能
Feb 22 Javascript
用ES6的class模仿Vue写一个双向绑定的示例代码
Apr 20 Javascript
JS实现字符串去重及数组去重的方法示例
Apr 21 Javascript
Vue切换组件实现返回后不重置数据,保留历史设置操作
Jul 21 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在线解压ZIP文件的方法
2014/12/30 PHP
PHP 匿名函数与注意事项详细介绍
2016/11/26 PHP
JS图片浏览组件PhotoLook的公开属性方法介绍和进阶实例代码
2010/11/09 Javascript
IE的事件传递-event.cancelBubble示例介绍
2014/01/12 Javascript
基于jquery实现鼠标滚轮驱动的图片切换效果
2015/10/26 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
javascript 初学教程及五子棋小程序的简单实现
2017/07/04 Javascript
详解Vue学习笔记入门篇之组件的内容分发(slot)
2017/07/17 Javascript
angular中ui calendar的一些使用心得(推荐)
2017/11/03 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
2018/02/01 Javascript
JS中的BOM应用
2018/02/02 Javascript
JS实现字体背景跑马灯
2020/01/06 Javascript
[42:20]2014 DOTA2华西杯精英邀请赛5 24 DK VS NewBee
2014/05/25 DOTA
Python httplib,smtplib使用方法
2008/09/06 Python
Python高效编程技巧
2013/01/07 Python
Python实现运行其他程序的四种方式实例分析
2017/08/17 Python
Python使用Matplotlib模块时坐标轴标题中文及各种特殊符号显示方法
2018/05/04 Python
Django多数据库的实现过程详解
2019/08/01 Python
Python发送邮件的实例代码讲解
2019/10/16 Python
Django项目使用ckeditor详解(不使用admin)
2019/12/17 Python
Python3操作MongoDB增册改查等方法详解
2020/02/10 Python
keras.utils.to_categorical和one hot格式解析
2020/07/02 Python
vscode+PyQt5安装详解步骤
2020/08/12 Python
Visual Studio code 配置Python开发环境
2020/09/11 Python
matplotlib部件之套索Lasso的使用
2021/02/24 Python
CSS 说明横向进度条最后显示文字的实现代码
2020/11/10 HTML / CSS
美国牛仔品牌:True Religion
2018/11/16 全球购物
英国健身超市:Fitness Superstore
2019/06/17 全球购物
园林设计师自荐信
2013/11/18 职场文书
2014年话务员工作总结
2014/11/19 职场文书
开除通知书范本
2015/04/25 职场文书
css3 利用transform-origin 实现圆点分布在大圆上布局及旋转特效
2021/04/29 HTML / CSS
5分钟教你docker安装启动redis全教程(全新方式)
2021/05/29 Redis
Canvas绘制像素风图片的示例代码
2021/09/25 HTML / CSS
Go语言实现一个简单的并发聊天室的项目实战
2022/03/18 Golang
SQL Server远程连接的设置步骤(图文)
2022/03/23 SQL Server