JavaScript中的稀疏数组与密集数组[译]


Posted in Javascript onSeptember 17, 2012

1.稀疏数组
创建一个指定长度的稀疏数组很简单:

> var a = new Array(3); 
> a 
[ , , ] 
> a.length 
3 
> a[0] 
undefined

当你遍历它时,你会发现,它并没有元素.JavaScript会跳过这些缝隙.
> a.forEach(function (x, i) { console.log(i+". "+x) }); 
> a.map(function (x, i) { return i }) 
[ , , ]

译者注:还有一些其他情况会生成稀疏数组,比如
>var arr = []; 
>arr[0] = 0; 
>arr[100] = 100>a.forEach(function (x, i) { console.log(i+". "+x) });0. 0100. 100

2.密集数组

Brandon Benvie 最近在es-discuss邮件讨论组中提到了一个创建密集数组的技巧:

> var a = Array.apply(null, Array(3)); 
> a 
[ undefined, undefined, undefined ]

上面的语句其实等同于:

Array(undefined, undefined, undefined)

但从表面上看,貌似这个数组和之前的稀疏数组并没有太多的区别:

> a.length 
3 
> a[0] 
undefined

可是,你现在可以遍历到这些数组元素了,还可以为每个元素重新赋值:
> a.forEach(function (x, i) { console.log(i+". "+x) }); 
0. undefined 
1. undefined 
2. undefined > a.map(function (x, i) { return i }) 
[ 0, 1, 2 ]

译者注:实际上,JavaScript并没有常规的数组,所有的数组其实就是个对象,只不过会自动管理一些"数字"属性和length属性罢了.说的更直接一点,JavaScript中的数组根本没有索引,因为索引应该是数字,而JavaScript中数组的索引其实是字符串.arr[1]其实就是arr["1"],给arr["1000"] = 1,arr.length也会自动变为1001.这些表现的根本原因就是,JavaScript中的对象就是字符串到任意值的键值对.注意键只能是字符串.这和AWK类似.不信可以试试awk 'BEGIN{a[1]=1;print(a["1"])}'.也许这是因为Brendan Eich在发明JavaScript时参考了不少awk的设计的原因.不过目前,ES6中已经有了类似于Java等语言的Map类型,键可以是任意类型的值.请参考我翻译的MDN文档Map

3.另一个技巧
邮件里还提到了另外一个技巧:

> Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number)) 
[ 0, 1, 2 ]

这大概等同于下面的写法
Array.apply(null, Array(3)).map( 
function (x,i,...) { return Number.call(x,i,...) })

注意,x是call方法的第一个参数,它作为了Number函数中的this值.这个值没有什么意义,相当于被忽略.我更喜欢下面这个能让人一眼就看明白的写法:
Array.apply(null, Array(3)).map(function (x,i) { return i })

译者注:
Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number)) 
//等同于Array.apply(null, Array(3)).map(Function.prototype.call,Number)

虽然使用自定义的函数更清晰,但自定义的函数肯定没有原生方法快.举个例子:
var a = ["aaa ", " bbb", " ccc "] 
a.map(function(x) { return x.trim(); }); // ['aaa', 'bbb', 'ccc'] 
a.map(Function.prototype.call, String.prototype.trim); // ['aaa', 'bbb', 'ccc']

上面使用map方法来trim掉每个数组元素的空格,使用原生的方法虽然难理解.但效率高.看不懂的可以查看下我翻译的MDN文档Array.prototype.map()

4.实际用途?

在实际生产中,使用上面讲的创建密集数组的方法会让别人无法读懂你的代码.所以封装成一个工具函数会更好,比如 _.range:

> _.range(3) 
[ 0, 1, 2 ]

和map配合使用,可以使用某个指定的值填充整个数组.
> _.range(3).map(function () { return "a" }) 
[ 'a', 'a', 'a' ]

译者注:其他语言里,都有方便的生成递增数字列表的办法,比如perl和ruby里使用1..100,python里使用range(100),还有一个常见的需求就是生成一个重复某个字段的字符串,在ruby和python里,可以用"a"*100,在perl里用"a"x100,在JavaScript中,可以用Array(100).join("a")

5.相关文章

  1. Iterating over arrays and objects in JavaScript(已墙)
  2. Trying out Underscore on Node.js(已墙)
Javascript 相关文章推荐
Jquery插件之多图片异步上传
Oct 20 Javascript
jquery animate图片模向滑动示例代码
Jan 26 Javascript
获取body标签的两种方法
Oct 13 Javascript
jquery随机展示头像代码
Dec 21 Javascript
jQuery之ajax技术的详细介绍
Jun 19 Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 Javascript
在js里怎么实现Xcode里的callFuncN方法(详解)
Nov 05 Javascript
JavaScript中关于iframe滚动条的去除和保留
Nov 17 Javascript
微信小程序 scroll-view隐藏滚动条详解
Jan 16 Javascript
webpack常用构建优化策略小结
Nov 21 Javascript
使用JavaScript计算前一天和后一天的思路详解
Dec 20 Javascript
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 Vue.js
JavaScript中:表达式和语句的区别[译]
Sep 17 #Javascript
JavaScript取得鼠标绝对位置程序代码介绍
Sep 16 #Javascript
JavaScript高级程序设计 阅读笔记(二十一) JavaScript中的XML
Sep 14 #Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
Sep 14 #Javascript
javascript时区函数介绍
Sep 14 #Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
Sep 14 #Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
Sep 14 #Javascript
You might like
php mysql 判断update之后是否更新了的方法
2012/01/10 PHP
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
点击广告后才能获得下载地址
2006/10/26 Javascript
从父页面读取和操作iframe中内容方法
2009/07/25 Javascript
『jQuery』名称冲突使用noConflict方法解决
2013/04/22 Javascript
jquery 无限级下拉菜单的简单实现代码
2014/02/21 Javascript
Javascript生成带参数的二维码示例
2016/10/10 Javascript
基于jQuery的左滑出现删除按钮的示例
2017/08/29 jQuery
React Native预设占位placeholder的使用
2017/09/28 Javascript
修改UA在PC中访问只能在微信中打开的链接方法
2017/11/27 Javascript
html中通过JS获取JSON数据并加载的方法
2017/11/30 Javascript
使用async-validator编写Form组件的方法
2018/01/10 Javascript
详解如何在React组件“外”使用父组件的Props
2018/01/12 Javascript
深入理解vue中slot与slot-scope的具体使用
2018/01/26 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
2018/08/06 Javascript
vue路由跳转传参数的方法
2019/05/06 Javascript
在vue中实现给每个页面顶部设置title
2020/07/29 Javascript
Python实现基于二叉树存储结构的堆排序算法示例
2017/12/08 Python
python3 遍历删除特定后缀名文件的方法
2018/04/23 Python
Python 忽略warning的输出方法
2018/10/18 Python
python 利用for循环 保存多个图像或者文件的实例
2018/11/09 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
2020/02/27 Python
css3高级选择器使用方法
2013/12/02 HTML / CSS
html5 localStorage本地存储_动力节点Java学院整理
2017/07/06 HTML / CSS
来自全球大都市的高级街头服饰:Pegador
2018/01/03 全球购物
网站设计师的岗位职责
2013/11/21 职场文书
结婚邀请函范文
2014/01/14 职场文书
煤矿机修工岗位职责
2014/02/07 职场文书
《胡杨》教学反思
2014/02/16 职场文书
施工员岗位职责
2014/03/16 职场文书
学员自我鉴定
2014/03/19 职场文书
离职证明范本(5篇)
2014/09/19 职场文书
2014年师德师风自我剖析材料
2014/09/27 职场文书
2015年办公室主任工作总结
2015/04/09 职场文书
张丽莉事迹观后感
2015/06/16 职场文书
关于开学的感想
2015/08/10 职场文书