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

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(已墙)

(0)

相关推荐

  • js数组去重的hash方法

    对于 JavaScript 数组去除重复项,现在有多种方法,其中一种是hash,如下: if (!Array.prototype.unique) { Array.prototype.unique = function () { var hash = {}, result = [], item; for (var i = 0; i < this.length; i++) { item = this[i]; if ( !hash[item] ) { hash[item] = true; result

  • javascript稀疏数组(sparse array)和密集数组用法分析

    本文实例讲述了javascript稀疏数组(sparse array)和密集数组用法.分享给大家供大家参考,具体如下: 学习underscore.js数组相关API的时候,遇到了sparse array这个东西,以前没有接触过. 这里学习下什么是稀疏数组和密集数组. 什么是密集数组呢?在Java和C语言中,数组是一片连续的存储空间,有着固定的长度.加入数组其实位置是address,长度为n,那么占用的存储空间是address[0],address[1],address[2].......addr

  • 体验js中splice()的强大(插入、删除或替换数组的元素)

    处理数组的方法很多,javascript splice()算是最强大的了,它可以用于插入.删除或替换数组的元素.下面来一一介绍! 1.删除-用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数) 2.插入-向数组指定位置插入任意项元素.三个参数,第一个参数(其实位置),第二个参数(0),第三个参数(插入的项) 3.替换-向数组指定位置插入任意项元素,同时删除任意数量的项,三个参数.第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项) 看下

  • js数组循环遍历数组内所有元素的方法

    例,for(){}遍历数组 复制代码 代码如下: <script type="text/javascript"> <!--var arr = new Array(13.5,3,4,5,6);for(var i=0;i<arr.length;i++){ arr[i] = arr[i]/2.0;}alert(arr); //--> </script> 例,for in循环遍历数组 复制代码 代码如下: <html><body>

  • JS array 数组详解

    1.数组的声明方法 (1): arrayObj = new Array(); //创建一个数组. 复制代码 代码如下: var arr1 = new Array(); (2):arrayObj = new Array([size]) 创建一个数组并指定长度,注意不是上限,是长度. 复制代码 代码如下: var a = new Array(5); (3):arrayObj = new Array([element0[, element1[, ...[, elementN]]]]) 创建一个数组并赋

  • Javascript 数组去重的方法(四种)详解及实例代码

     Javascript 数组去重的四种方法 四种算法来实现这个目的: 第一种方法: Array.prototype.unique1 = function () { var n = []; //一个新的临时数组 for (var i = 0; i < this.length; i++) //遍历当前数组 { //如果当前数组的第i已经保存进了临时数组,那么跳过, //否则把当前项push到临时数组里面 if (n.indexOf(this[i]) == -1) n.push(this[i]); }

  • js二维数组定义和初始化的三种方法总结

    方法一:直接定义并且初始化,这种遇到数量少的情况可以用 var _TheArray = [["0-1","0-2"],["1-1","1-2"],["2-1","2-2"]] 方法二:未知长度的二维数组 var tArray = new Array(); //先声明一维 for(var k=0;k<i;k++){ //一维长度为i,i为变量,可以根据实际情况改变 tArray[k]

  • javascript 数组去重复(在线去重工具)

    在线文本去重复工具 第一种方法: <textarea id="list" class="toolarea">我们 www.jb51.net www.baidu.com www.jb51.net 我们 shouce.jb51.net www.jb51.net tools.jb51.net www.baidu.com shouce.jb51.net tools.jb51.net 我们 www.jb51.net</textarea> <inp

  • js数组与字符串的相互转换方法

    熟悉js的朋友很多都遇到过js的数组与字符串相互转换的情况,本文就此作一简单介绍,示例如下: 一.数组转字符串 需要将数组元素用某个字符连接成字符串,示例代码如下: var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); 二.字符串转数组 实现方法为将字符串按某个字符切割成若干个字符串,并以数组形式返回,示例代码如下: var s = "abc,abcd,aaa"; ss = s.split(","

  • JS克隆,属性,数组,对象,函数实例分析

    本文实例讲述了JS克隆,属性,数组,对象,函数.分享给大家供大家参考,具体如下: <script type="text/javascript"> /* 克隆原型得到对象 */ function clone(object) { function F() {} F.prototype = object; return new F; } var Person = { name: 'default name', getName: function() { return this.n

  • js中通过split函数分割字符串成数组小例子

    复制代码 代码如下: <script language="javascript"> str="2,2,3,5,6,6"; //这是一字符串 var strs= new Array(); //定义一数组 strs=str.split(","); //字符分割 for (i=0;i<strs.length ;i++ ) { document.write(strs[i]+"<br/>"); //分割后的

  • javascript数组去重方法分析

    本文实例讲述了javascript数组去重方法.分享给大家供大家参考,具体如下: 方法一. 思路:创建一个新的空数组,循环遍历旧数组,用indexOf()方法,可以取得元素在数组中的位置,如果值为-1表示不存在.那么新数组用indexOf去获取老数组的每一个元素,如果值为-1表示不存在,就把他push到新数组里,最后输出新数组即去重后的数组 var arr=[24,56,74,89,24,56,78,09,24]; var new_arr=[]; for(var i=0;i<arr.length

  • 详解JavaScript中数组的reduce方法

    介绍 我们先来看看这个方法的官方概述:reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值. 你一定也和我一样看的有点迷糊,其实reduce接收的就是一个回调函数,去调用数组里的每一项,直到数组结束. 我们来举个例子大家就很明白了. 假设我有一串数组,数组里放的全是数字,我要算出这些数字的总和是多少.正常情况下我们会循环,然后一个个加,有了reduce就不用那么麻烦了,只用一行代码. var total = [0,1,2,3,4

随机推荐