属性
Array.length
属性,获取与定义数组长度。
var arr = [1, 2, 3];
arr.length;
arr.length = 2;
console.log(arr); // [1, 2]
操作方法
Array.concat
创建当前数组的副本,未传递参数直接返回副本,可接收多参数,返回拼接后的数组。
var arr = [1, 2, 3];
var b = arr.concat(4, [5, 6]);
var c = arr.concat();
console.log(b); // [1, 2, 3, 4, 5, 6]
console.log(c); // [1, 2, 3]
Array.slice
基于当前数组的一项或多项创建新数组。接收一或两个参数,分别代表开始与结束位置。未传递参数直接返回数组副本。
当只传递开始位置时,返回至结尾所有项。传递开始与结束位置时,返回开始至结束位置-1
的项。
var arr = [1, 2, 3, 4, 5];
arr.slice(); // [1, 2, 3, 4, 5]
arr.slice(2); // [3, 4, 5]
arr.slice(2,4); // [3, 4]
Array.splice
splice()
主要用于向数组的中部插入项,有删除、插入、替换三种用法。调用结果始终返回一个数组,包含从原始出自中删除的项,无删除则返回空数组。
删除
可以删除任意数次量的项,需指定两个参数:起始位置,删除的项数。
var arr = [1, 2, 3, 4, 5];
var removed = arr.splice(1, 1);
console.log(removed); // [2]
console.log(arr); // [1, 3, 4, 5]
插入
可以向指定位置插入任意数量的项,需提供三个参数:起始位置,0(删除0项),要插入的项。若插入多项,可以继续追加多个参数。
var arr = [1, 2, 3, 4, 5];
var removed = arr.splice(1, 0, 'blue', 'red');
console.log(removed); // []
console.log(arr); // [1, "blue", "red", 2, 3, 4, 5]
替换
可以向指定位置插入任意多的项,且同时删除任意数量的项,需指定三个参数:起始位置,要删除的项数,要插入的任意数量的项。插入的项数可不与删除的项数相等。
var removed = [1, 2, 3, 4, 5];
var res = removed.splice(1, 1, 'red', 'blue');
console.log(removed); // [2]
console.log(arr); // [1, "red", "blue", 3, 4, 5]
迭代方法
ECMAScript5
为数组提供5个迭代方法,每个方法都接收两个参数:每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this
的值。传入这些方法的函数接收三个参数:数组项的值,该项在数组中的位置和数组对象本身。这几个迭代方法都不会改变原数组。
var arr = [1, 2, 3, 'blue', 'red'];
function isNum(item, index, array) {
return typeof item == 'number';
}
Array.every
对数组中的每一项运行给定函数,如果该函数对每一项都返回true
,则返回true
。
arr.every(isNum); // false
Array.filter
对数组中的每一项运行给定函数,返回该函数会返回true
的项组成的数组。
arr.filter(isNum); // [1, 2, 3]
Array.map
对数组中的每一项运行给定函数,返回每次调用的结果组成的数组。
arr.map(isNum); // [true, true, true, false, false]
Array.some
对数组中的每一项运行给定函数,如果函数对任一项返回true
,则返回true
。
arr.some(isNum); // true
Array.forEach
对数组中的每一项运行给定函数,无返回值。
arr.forEach(function(item, index, array) {
array[index] = item + '##';
});
console.log(arr); // ["1##", "2##", "3##", "blue##", "red##"]
小结
每个迭代方法均对数组每一项执行判定函数,迭代后没有副作用。
判定系
Array.some // 有一项返回true,则返回true
Array.every // 每一项返回true,则返回true
返回结果数组
Array.map // 返回每一项调用后的结果组成的新数组
Array.filter // 过滤,返回执行结果为true的项组成的数组
无返回值
Array.forEach // 对每一项执行函数,无返回值
Array.map
与Array.filter
接近,区别在于有无结果返回值。
栈和队列
栈方法
栈是一种后进先出的数据结构,最后添加的项最早被移除。只在栈的顶部发生数据变换。
Array.push
接收任意数目的参数,将他们逐个追加至数组末尾,返回改变后的数组长度。
[].push('blue', 'red', 'green'); // 3
Array.pop
从数组末尾移除一项,将数组长度-1,返回被移除的项。
['blue', 'red', 'green'].pop(); // 'green'
队列方法
队列是一种先进先出的数据结构,在列表末端添加项,从列表前端移除项。
Array.shift
移除数组的首项并返回该项,同时将数组长度-1。利用push()
与shift()
可以模拟队列。
['blue', 'red', 'green'].shift(); // 'blue'
Array.unshift
在数组前端添加任意个项并返回新数组的长度。利用pop()
与unshift()
可以模拟反队列。
['blue', 'red', 'green'].unshift('yellow', 'black'); // 5
查找元素位置
Array.indexOf
Array.lastIndexOf
严格比较(===
),接收两个参数,要查找的数组项,从第几个位置开始查找。返回匹配项位置索引,没有则返回-1。
indexOf()
返回匹配项第一次出现的位置,lastIndexOf()
返回最后一次出现的位置。
[1, 2, 'blue', 4, 'blue', 'red'].indexOf('blue'); // 2
[1, 2, 'blue', 4, 'blue', 'red'].indexOf('blue',3); // 4
[1, 2, 'blue', 4, 'blue', 'red'].lastIndexOf('blue'); // 4
数组排序
Array.reverse
对数组降序排列。
[1, 2, 3].reverse() // [3, 2, 1]
Array.sort
默认将数组各项转型为字符串相比较,对结果升序排列。可接收一个比较函数,自定义排序规则。
[2, 3, 10, 5].sort(); // [10, 2, 3, 5]
function compare(a, b) {
return a-b;
}
// compare>0:a>b,compare=0:a=b,compare<0:a<b
[2, 3, 10, 5].sort(compare); // [2, 3, 5, 10]
数组转字符串
Array.toLocaleString
Array.toString
返回数组的字符串形式,以逗号分割。生成结果时将调用数组每一项的toString()
方法。
var arr = ["red", "yellow", "green"];
arr.toString(); // "red, yellow,green"
arr.toLocaleString(); // "red, yellow,green"
Array.join
将所有数组项拼接为一个字符串返回,各项间以指定分隔符分割。
["yellow", "black", 1, 2, 3].join() // "yellow,black,1,2,3"
["yellow", "black", 1, 2, 3].join("+") // "yellow+black+1+2+3"
其他方法
Array.isArray
ECMAScript 5
方法,判断是否为数组。
Array.isArray([2, 3]); // true
[2, 3] instanceof Array // true
Array.entries
ECMAScript 6
方法,返回一个新的数组迭代器对象,每一项值为原数组的键值对形式。
var eArr =['a', 'b', 'c'].entries();
console.log(eArr.next().value); // [0, 'a']
console.log(eArr.next().value); // [1, 'b']
console.log(eArr.next().value); // [2, 'c']
总结
克隆数组
concat()
方法和slice()
方法在未传递参数时会返回当前数组的副本,我们可以利用这一特性来克隆一个数组。注意这种方式是浅拷贝,如果数组中包含对象,将拷贝对象的引用而不是实体。
var arr = [1, 2, 3];
var narr = arr.concat(); // [1, 2, 3]
var narr2 = arr.slice(); // [1, 2, 3]
删除数据项
shift()
删除首项pop()
删除尾项splice(i, n)
删除中间任意项
这几个方法均返回被移除的项,其中splice()
以数组形式返回。
遍历
for...in
遍历数组下标的字符串形式,同时也会遍历Array.prototype
上的属性,有可能带导致意外的结果。
推荐使用传统for
循环、for...of
或Array
自身的迭代方法遍历数组值。
在Array
自身的几个迭代方法中filter()
,map()
结果值为数组。
数据项
默认数据项或不存在的数据项值为undefined
,判断空数据项用typeof
操作符。
var arr = [];
arr[1] = 2;
arr[3] = 4;
console.log(arr[0]); // undefined
console.log(arr[5]); // undefined
typeof arr[5] == 'undefined' // true
转换类数组对象
可以将函数内部的arguments
等类数组对象转换为数组。
(function(a,b) {
var arr = [].slice.call(arguments);
console.log(arr); // [1, 2, 3, 4]
})(1, 2, 3, 4);
算法练习
移除数组中的元素
移除数组 arr 中的所有值与 item 相等的元素,请直接在给定的 arr 数组上进行操作 。
输入例子:
removeWithoutCopy([1, 2, 2, 3, 4, 2, 2], 2)
输出例子:
[1, 3, 4]
// 方法1:重写数组
function removeWithoutCopy(arr, item) {
var n = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] != item) {
arr[n++] = arr[i];
}
}
arr.length = n;
return arr;
}
// 方法2:遍历剔除
function removeWithoutCopy(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) {
arr.splice(i, 1);
i--;
}
}
return arr;
}
// 方法3:通过Array.indexOf()方法
function removeWithoutCopy(arr, item) {
var index = arr.indexOf(item);
while(index!=-1){
arr.splice(index,1);
index = arr.indexOf(item);
}
return arr;
}
查找重复元素
找出数组 arr 中重复出现过的元素 。
输入例子:
duplicates([1, 2, 4, 4, 3, 3, 1, 5, 3]).sort()
输出例子:
[1, 3, 4]
// 方法1:
function duplicates(arr) {
var res = [];
arr.forEach(function(v) {
if(arr.indexOf(v) !== arr.lastIndexOf(v)) {
(res.indexOf(v) == -1) && res.push(v)
// 剔除数组重复项,并返回由被剔除重复项组成的数组
//(res.indexOf(v) == -1) && res.push(a.splice(i,1)[0]);
}
});
return res;
}
// 方法2:
function duplicates(arr) {
var s = {},
res = [];
arr.forEach(function(a) {
if(!s[a+'']) s[a+''] = 1;
else if(s[a+''] === 1) {res.push(a); s[a+''] = 2}
});
return res
}
// 方法3:
function duplicates(arr) {
var ary = arr.sort(),
len = arr.length,
for(var i=0;i<len;i++){
if (ary[i-1]==ary[i] && ary[i]!=ary[i+1]){
res.push(ary[i]);
}
}
return res;
}
二次封装函数*
实现函数 partialUsingArguments,调用之后满足如下条件:
1. 返回一个函数 result
2. 调用 result 之后,返回的结果与调用函数 fn 的结果一致
3. fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
输入例子:
var a = 1;
var b = 2;
var c = 3;
var d = 4;
var test = function (first, second, third, forth) {
return first + second + third + forth;
};
partialUsingArguments(test, a, b)(c, d);
输出例子:
10
function partial(fn, str1, str2) {
var arr = [].slice.call(arguments, 1)
return function() {
return fn.apply(null, arr.concat([].slice.call(arguments)))
}
}