详解JavaScript中数组的相关知识
创建数组
js中数组的声明可以有如下几种方式:
var arr = []; // 简写模式 var arr = new Array(); // new一个array对象 var arr = new Array(arrayLength); // new一个确定长度的array对象
要说明的是:
- 虽然第三种方法声明了数组的长度,但是实际上数组长度是可变的。也就是说,即使指定了长度为5,仍然可以将元素存储在规定长度之外,这时数组的长度也会随之改变。
- 此外,还需要明确的一点:
- js是弱类型语言,也就是数组中的元素类型不需要一样。
举个数组中元素类型不一致的例子:
var arr = [1, 2, 3, 4, 'wangzhengyi', 'bululu']; for (var i = 0; i < arr.length; i ++) { console.log(arr[i]); }
数组元素访问
JavaScript数组的索引值也是从0开始的,我们可以直接通过数组名+下标的方式对数组元素进行访问。
示例代码如下:
var arr = [1, 2, 3]; console.log(arr[0]); console.log(arr[1]);
此外,数组的遍历推荐使用连续for循环的模式,不推荐for-in,具体原因参考:Loop through array in JavaScript
遍历数组示例代码如下:
var arr = [1, 2, 3, 4, 'wangzhengyi', 'bululu']; for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); }
注意:
上述代码中,一个小优化在于提前获取数组的大小,这样不需要每次遍历都去查询数组大小。对于超大数组来说,能提高一定的效率。
添加数组元素
有三种方法可以往一个数组中添加新的元素,分别是:push、unshift、splice。下面我分别来介绍一下这三种方法。
push
push方法,在数组末尾添加元素。示例代码如下:
var arr = []; arr.push(1); arr.push(2); arr.push(3); for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); }
执行结果为:
1 2 3
unshift
unshift方法,是在数组头部添加元素。示例代码如下:
var arr = []; arr.unshift(1); arr.unshift(2); arr.unshift(3); for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); }
执行结果如下:
3 2 1
splice
splice方法是在数组的指定位置插入新元素,之前的元素则是自动顺序后移。注意splice的函数原型为:
array.splice(index, howMany, element...)
howMany表示要删除的元素个数,如果只是添加元素,此时howMany需要置为0。
示例代码如下:
var arr = [1, 2, 3, 4]; arr.splice(1, 0, 7, 8, 9); for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); }
执行结果如下:
1 7 8 9 2 3 4
删除数组元素
与增加数组元素一样,删除数组中的元素也有三个方法,分别是:pop、shift和splice。接下来,分别讲解一下这三个函数的用法。
pop
pop方法是移除数组中的最后一个元素。push和pop的组合可以将数组实现类似于栈(先入后出)的功能。示例代码如下:
var arr = []; arr.push(1); arr.push(2); arr.push(3); while (arr.length != 0) { var ele = arr.pop(); console.log(ele); }
shift
shift方法是移除第一个元素,数组中的元素自动前移。(这种方法肯定对应着效率问题,时间复杂度是O(n))。
var arr = []; arr.push(1); arr.push(2); arr.push(3); function traverseArray(arr) { for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); } } while (arr.length != 0) { var ele = arr.shift(); traverseArray(arr); }
大家可以自己考虑运行结果。
splice
在增加数组元素的时候,我们就讲过splice,这个函数原型中有一个howMany参数,代表从index开始删除之后的多少个元素。
示例代码如下:
var arr = [1, 2, 3, 4, 5, 6, 7]; function traverseArray(arr) { for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); } } arr.splice(1, 3); traverseArray(arr);
执行结果为:
1 5 7
数组的拷贝和截取
举个例子,代码如下:
var arr1 = [1, 2, 3, 4]; var arr2 = arr1;
这个时候,arr2只是保存arr1数组在堆内存的地址,并没有在堆内存重新申请内存搞一个数组出来。所以对arr2的修改会同时影响到arr1。因此,如果我们需要拷贝一份数组该怎么做呢?这就引出了需要学习的slice和concat函数。
slice
这里的slice和python语法的slice是一样的,都是返回数组的切片。slice函数原型为:
array.slice(begin, end)
返回从begin到end的所有元素,注意包含begin,但是不包含end。
缺省begin,默认从0开始。缺省end,默认到数组末尾。
因此,拷贝数组我们可以通过如下代码实现:
var arr1 = [1, 2, 3, 4]; var arr2 = arr1.slice(); arr2[2] = 10000 function traverseArray(arr) { for (var i = 0, len = arr.length; i < len; i ++) { console.log(arr[i]); } } traverseArray(arr1); traverseArray(arr2);
执行结果如下:
1 2 3 4 1 2 10000 4
concat
concat方法将创建一个新数组,然后将调用它的对象(this 指向的对象)中的元素以及所有参数中的数组类型的参数中的元素以及非数组类型的参数本身按照顺序放入这个新数组,并返回该数组.
示例代码如下:
var alpha = ["a", "b", "c"]; var number = [1, 2, 3] // 新数组为["a", "b", "c", 1, 2, 3] var complex = alpha.concat(number);