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 相关文章推荐
Javascript与flash交互通信基础教程
Aug 07 Javascript
dess中一个简单的多路委托的实现
Jul 20 Javascript
JS仿flash上传头像效果实现代码
Jul 18 Javascript
面向对象设计模式的核心法则
Nov 10 Javascript
JS小功能(checkbox实现全选和全取消)实例代码
Nov 28 Javascript
简介JavaScript中valueOf()方法的使用
Jun 05 Javascript
js判断浏览器类型及设备(移动页面开发)
Jul 30 Javascript
解析JavaScript面向对象概念中的Object类型与作用域
May 10 Javascript
Node.js 实现简单小说爬虫实例
Nov 18 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
Sep 28 Javascript
微信小程序日历/日期选择插件使用方法详解
Dec 28 Javascript
JS+canvas五子棋人机对战实现步骤详解
Jun 04 Javascript
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去除数组中重复的元素并按键名排序函数
2008/08/18 PHP
php面向对象全攻略 (七) 继承性
2009/09/30 PHP
谈谈你对Zend SAPIs(Zend SAPI Internals)的理解
2015/11/10 PHP
在laravel-admin中列表中禁止某行编辑、删除的方法
2019/10/03 PHP
javascript 解决表单仍然提交即使监听处理函数返回false
2010/03/14 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
javascript数组操作总结和属性、方法介绍
2014/04/05 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
基于js对象,操作属性、方法详解
2016/08/11 Javascript
jQuery实现带遮罩层效果的blockUI弹出层示例【附demo源码下载】
2016/09/14 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
Three.js实现浏览器变动时进行自适应的方法
2017/09/26 Javascript
bootstrap 通过加减按钮实现输入框组功能
2017/11/15 Javascript
Angularjs实现页面模板清除的方法
2018/07/20 Javascript
js根据json数据中的某一个属性来给数据分组的方法
2018/10/08 Javascript
three.js欧拉角和四元数的使用方法
2020/07/26 Javascript
提升Python程序运行效率的6个方法
2015/03/31 Python
python 判断网络连通的实现方法
2018/04/22 Python
浅析python3字符串格式化format()函数的简单用法
2018/12/07 Python
对python requests发送json格式数据的实例详解
2018/12/19 Python
Python实现定时自动关闭的tkinter窗口方法
2019/02/16 Python
3行Python代码实现图像照片抠图和换底色的方法
2019/10/10 Python
python 利用jinja2模板生成html代码实例
2019/10/10 Python
python模块和包的应用BASE_PATH使用解析
2019/12/14 Python
Python-openCV开运算实例
2020/07/05 Python
解决Django响应JsonResponse返回json格式数据报错问题
2020/08/09 Python
简单的命令查看安装的python版本号
2020/08/28 Python
Jmeter调用Python脚本实现参数互相传递的实现
2021/01/22 Python
用HTML5制作烟火效果的教程
2015/05/12 HTML / CSS
英国购买威士忌网站:Master of Malt
2019/09/26 全球购物
SEPHORA丝芙兰德国官方购物网站:化妆品、护肤品和香水
2020/01/21 全球购物
教学改革实施方案
2014/03/31 职场文书
2014幼儿园中班工作总结
2014/11/10 职场文书
2014年学校德育工作总结
2014/12/05 职场文书
小学体育跳绳课教学反思
2016/02/16 职场文书
Vue+Element UI实现概要小弹窗的全过程
2021/05/30 Vue.js