主要介绍数组的一些常用的方法,方法多了,就容易混淆,结果就是方法用错,甚至不会用:
一.数组的定义:
1.字面量/直接量: var arr = [1, 2, 'js', 'java'];
2.通过内部数组对象Array来创建数组: var arr = new Array(length/ content);(注意当括号内传入的仅仅一个值,且其为整数的情况,该值是作为数组长度,而不是数组的第一个元素内容)
二.稀疏数组和密集数组:
1.稀疏数组即数组中存在位置数组未定义,其值为undefined, 而密集数组中每个位置都定义了确定的数值。
2.稀疏数组产生方式:
(1)字面量产生
var arr = [1, 2, ,4,]; console.log(arr.length); // 4 console.log(arr[2]); // undefined
//注意:如果字面量定义数组,最后一个内容为逗号,则解释器会自动忽略最后一个逗号的存在
(2)针对字面量或数组对象,溢出写产生
var arr = [0, 1, 2]; console.log(arr.length); // 3 arr[5] = 5; console.log(arr.length); // 6 console.log(arr[4]); // undefined
三.类数组:
1.可以利用对象的属性名来模拟数组的特性
2.可以动态的增长length属性
3.如果强行让类数组调用push方法,则会根据了length属性值的位置进行属性的扩充。
var arrObj = { 0: 1, 1: 2, length: 2, push: Array.prototype.push, sort: Array.prototype.sort, splice: Array.prototype.splice } console.log(arrObj.length); // 2 arrObj.push(3); console.log(arrObj[2]); // 3 console.log(arrObj.length); // 3 //注意:一般在类数组中添加length,push,sort,splice这四个属性,该对象就差不多可以拥有数组的基本特性
四.数组的一些方法及其注意事项:
1.方法分类:
改变原数组的方法:reverse,sort,push,pop,shift,unshift,splice
不改变原数组的方法:concat,join——>split,toString
2.改变原数组的方法:
(1)reverse:数组逆序
var arr = [1, 2, 3, 4, 5]; arr.reverse(); console.log(arr); // [5, 4, 3, 2, 1]
(2)sort:对数组元素 进行排序
/*默认为升序排序*/
var arr = [1, 3, 2, 5, 4]; arr.sort(); console.log(arr); // [1, 2, 3, 4, 5]
// 可传参,参数形式为函数 var arr = [1, 3, 2, 5, 4]; arr.sort(function (a, b){ //return 负数; a, b前后位置不变 //return 正数; a, b前后位置改变 /* 常用: return a - b; 升序 return b - a; 降序 return Math.random - 0.5; 乱序 */ });
(3)push: 向数组末尾添加若干个元素
var arr = [1, 2, 3]; arr.push(4, 5); console.log(arr); //[1, 2, 3, 4, 5]
(4)pop:从数组末尾剪切一个元素,并返回该元素
var arr = [1, 2, 3]; var ret = arr.pop(); console.log(arr); //[1, 2] console.log(ret); // 3
(5)unshift:向数组头部添加若干个元素
var arr = [1, 2, 3]; arr.unshift(0, -1); console.log(arr); //[-1, 0, 1, 2, 3]
(6)shift: 从数组头部剪切一个元素,并返回该元素
var arr = [1, 2, 3]; var ret = arr.shift(); console.log(arr); //[2, 3] console.log(ret); // 1
(7)splice(startIndex, length, addElements):从startIndex开始剪切length个元素,并返回,然后从startIndex位置开始添加addElements若干个元素
注意:1.若addElements为一个数组,则该数组会作为一个元素添加进去,而不会拆开该数组一个个添加
2.字符串无法应用该方法,会报错
var arr = [1, 2, 3, 4, 5, 6, 7]; var ret = arr.splice(1, 2); //从索引1位置开始剪切两个元素 console.log(arr); //[1, 4, 5, 6, 7] console.log(ret); //[2, 3]
var arr = [1, 2, 3, 4, 5, 6, 7]; var ret = arr.splice(1, 2, 3, 2, -1); //从索引1位置开始剪切两个元素, 然后从索引1位置开始添加若干个元素 console.log(arr); //[1, 3, 2, -1, 4, 5, 6, 7] console.log(ret); //[2, 3] // 注意:1.索引从0开始; 2.剪切元素包括开始位置; 3.添加的元素个数不一定要和剪切的元素个数一样,可多可少
3.不改变原数组的方法:
(1)concat: 将参数数组拼接到调用该方法的数组后面,形成一个新数组返回
注意:字符串也可应用该方法
var arr1 = [0 , 1, 2]; var arr2 = [3, 4, 5]; var retArr = arr1.concat(arr2); //将arr2数组拼接到arr1后面,形成一个新数组返回 console.log(retArr); // [0 , 1, 2, 3, 4, 5]
(2). join: 将调用该方法的数组中各元素用括号内制定字符连接成为一个字符串返回
var arr = [1, 2, 3, 4]; var ret = arr.join('-'); //将arr数组中的元素用'-'连接起来,形成一个字符串返回; 若不传参,则默认用','拼接起来 console.log(ret); //1-2-3-4
//数组中存在元素为数组,则不正常连接 var arr = [1, 2, 3, 4, [5, 6, 7, 8]]; var ret = arr.join('-'); console.log(ret); // 1-2-3-4-5,6,7,8
应用: 常用concat将多个数组拼接起来,然后利用join方法进行字符串拼接,而不用‘+’运算符进行大量字符串的拼接,因为‘+’运算符效率太低;
4.和数组方法相关的方法:
(1)split(separator, howmany): 将一个字符串根据指定分隔符(separator)分割为一个字符串数组(其中howmany指定返回数组的最大长度)
var str = '1-2-3-4'; var retArr = str.split('-'); //用'-'分隔符来分割str形成一个字符串数组 console.log(retArr); //["1", "2", "3", "4"]
var str = '1-2-3-4'; var retArr = str.split('-',2); //用'-'分隔符来分割str形成一个字符串数组, 返回数组最大长度为2 console.log(retArr); //["1", "2"]
(2)toString: 将调用该方法的值转换为字符串
注意:由于undefined,null没有原型,所以也就没有toString方法,所以除了undefined和null无法调用toString()方法外,其他值均可调用toString()方法;
5.ES5中数组方法:
forEach(), map(), filter(), every(), some(), reduce(), reduceRight(), indexOf(), lastIndexOf()
(1)forEach(): 从头到尾遍历数组,为每个元素调用指定的函数(不修改原数组,也不会返回新数组,仅仅执行指定函数而已)
arrName.forEach(function (value, index, arr)) 其中value为遍历的当前值,index为遍历的当前索引指针,arr为调用forEach的数组
var arr1 = [1, 2, 3, 4]; arr1.forEach(function (value, index, arr) { console.log('value = ' + value + ' index = ' + index + ' arr = ' + arr); });
/*
value = 1 index = 0 arr = 1,2,3,4
value = 2 index = 1 arr = 1,2,3,4
value = 3 index = 2 arr = 1,2,3,4
value = 4 index = 3 arr = 1,2,3,4
*/
注意:forEach无法在所有元素都传递给调用的函数之前终止遍历,即无法像在for循环中使用break结束循环,所以若想提前结束循环,必须把forEach方法放到一个try块中,并能抛出一个foreach.break异常,提前终止循环
//通过异常 抛出结束循环
var arr1 = [1, 2, 3, 4]; try { arr1.forEach(function (value, index){ if (index === 3) { console.log('try能跳出来吗?'); foreach.break = new Error('StopIteration'); // 在此处手动创造一个自己知道的错误,并通过次错误跳出forEach循环 }else { console.log(value); } }); }catch (e) { console.log(e.message); if(e.message === 'foreach is not defined') { console.log('try可以跳出来了'); }else { throw e; } } /* 1 1 2 3 try能跳出来吗? foreach is not defined try可以跳出来了 */
(2)map(): 将调用数组的每个元素传递给指定的函数,并返回一个数组,该数组为每个元素经过函数处理的返回值组成(不修改原数组,返回新数组)
arrName.map(function (value, index, arr)) 其中value为遍历的当前值,index为遍历的当前索引指针,arr为调用map的数组
var arr1 = [1, 2, 3, 4]; var retArr = arr1.map(function (value, index, arr) { return value * value; }) console.log(retArr); //[1, 4, 9, 16]
(3) filter(), 返回满足一定条件的调用数组的子集,传递的函数是用来逻辑判断的,返回值为true或false,活着能转化为true或false的值,若返回值为true或能转化为true的值,则判定该元素为新子集数组的成员(不修改原数组,返回新数组)
arrName.filter(function (value, index, arr)) 其中value为遍历的当前值,index为遍历的当前索引指针,arr为调用filter的数组
var arr1 = [1, 2, 3, 4]; var retArr = arr1.filter(function (value, index, arr) { return index < 3; //返回索引小于3的元素 形成一个新数组 }); console.log(retArr); //[1, 2, 3]
(4)some(), every() 对调用数组的逻辑判定, 为满足条件则返回true, 否则返回false
some(function (value, index, arr)), every(function (value, index, arr)) 其中value为遍历的当前值,index为遍历的当前索引指针,arr为调用some | every的数组
some(), every()区别: some()是传入判定函数针对调用数组中的元素判定,只要有一个元素满足判定条件,则返回true,若都不满足判定条件,则返回false
every()是传入判定函数针对调用数组中的数组判定,若所有元素都满足判定条件,则返回true,只要有一个元素不满足条件,则返回false
var arr1 = [1, 2, 3, 4]; var retSome = arr1.some(function (value, index, arr){ return value < 2; }); console.log(retSome); // true var retEvery = arr1.every(function (value, index, arr) { return value < 2; }); console.log(retEvery); // false
(5)reduce(), reduceRight() 使用指定的函数将数组元素进行组合,生成单个值(不改变原数组,返回一个值)
reduce(function (x, y), sValue) 其中x为到目前为止的化简操作累积的结果, sValue为初始值,当指定初始值时,x刚开始为sValue, 当没有指定初始值时,x刚开始为数组第一个元素, y为在调用数组中紧跟x之后的元素
reduce(), reduceRight()区别:reduce是按数组索引从小到大进行操作,而reduceRight是按数组索引从大到小进行操作
var arr1 = [1, 2, 3, 4]; var retValue = arr1.reduce(function (x, y) { return x * y; }, 1); console.log(retValue); // 24
(6)indexOf(), lastIndexOf() 搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引,如果没有找到就返回-1
indexOf(serchValue, sIndex); 其中searchValue为 要搜索的值, sIndex可选,为开始搜索的索引位置,若 不填此参数,则从头开始搜索
lastIndexOf(serchValue, offset); 此方法是从末尾开始搜索, offset为可选参数, 且offset为负值, 代表相对数组末尾的偏移量,若不填此参数, 则从 末尾开始搜索
var arr1 = [1, 2, 3, 4]; // indexOf console.log(arr1.indexOf(3)); // 2 console.log(arr1.indexOf(3, 2)); //2 console.log(arr1.indexOf(5)); // -1 // lastIndexOf console.log(arr1.lastIndexOf(3)); //2 console.log(arr1.lastIndexOf(3, -1)); //2 console.log(arr1.lastIndexOf(5)); //-1