这些新增的方法只有IE9或者Edge及chrome等现代浏览器才支持,IE8及以下就不支持了。不过,老的东西肯定是要被抛弃的,学习新东西是常态。
技术总是一波接一波更新,所以持续学习是技术人必须的技能。不然很容易被拍死在沙滩上。
数组迭代方法对每个数组项都要进行操作。
1、forEach()
为每个数组元素调用一次函数。这个函数可以称之为“回调函数”。返回值是undefined。不会修改原始数组,但是在callback中可能更改原始数组。
arr.forEach(callback[,thisArg]);
callback:
为数组中每个元素执行的函数,该函数接收三个参数:
currentValue 数组中正在处理的当前元素。
index 可选 数组中正在处理的当前元素的索引。
array 可选 forEach() 方法正在操作的数组。
thisArg:
可选 当执行回调函数时用作 this 的值(参考对象)。
forEach 方法按升序为数组中含有效值的每一项执行一次callback 函数,那些已删除或者未初始化的项将被跳过。
以前都是用for循环遍历数组,现在可以改用forEach()了,前提是浏览器支持。
var arr=['成都','重庆','北京','上海']; var city=[]; for(let i=0;i<arr.length;i++){ city.push(arr[i]); } //改成forEach() arr.forEach(function(value){ city.push(value); })
function logArray(value,index){ console.log('arr['+index+']='+value) } var arr=[1,2,,4,5,,7]; arr.forEach(logArray); //arr[0]=1 arr[1]=2 arr[3]=4 arr[4]=5 arr[6]=7
forEach 遍历的范围在第一次调用 callback 前就会确定。调用 forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()),之后的元素将被跳过。而且,不能中止遍历,除非报错。
var arr=[1,2,-Infinity,'2',50]; arr.forEach(function(num,index){ if(num===-Infinity){ arr.splice(index,2); } console.log(num); //1,2,-Infinity }) arr.forEach(function(num,index){ if(num===-Infinity){ arr.splice(index,2,Infinity,10); } console.log(num); //1,2,-Infinity,10,50 })
在DOM中,用querySelectorAll()返回的是NodeList节点集合,并不是真的数组,而是一种类数组。低版本不支持forEach()函数,所以升级浏览器吧。可以不用for循环了。
var oP=document.querySelectorAll('p'); console.log(oP); //NodeList(5) [p, p, p, p, p] oP.forEach(function(obj,index){ obj.innerHTML=index; });
具体参考:Array.prototype.forEach()
2、map()
和forEach()几乎一样的使用方法,参数都是一样的,差别在于map()函数会返回一个新数组。
var arr=[2,4,8,10]; var newArr=arr.map(function(x){ return x/2; }) console.log(newArr); //[1, 2, 4, 5]
map里面的回调函数也可以不是自定义的函数,可以是现有的内置函数。
var num=[2,15,'12','a']; var newNum=num.map(isNaN); //isNaN是一个函数,所以不能加()。 [false, false, false, true] var num=['1',2,'2.2e2',2.5e-3]; var newNum=num.map(Number);//[1, 2, 220, 0.0025]
但是要注意,有些函数有多个参数,可能会导致问题。
比如:parseInt(numString, [radix]),如果用这个函数的话,就会把数组的索引值当成了进制数。
numString:必选项。要转换为数字的字符串。
radix : 可选项。在 2 和 36 之间的表示 numString 所保存数字的进制的值。如果没有提供,则前缀为 '0x' 的字符串被当作十六进制,前缀为 '0' 的字符串被当作八进制。所有其它字符串都被当作是十进制的。
parseInt 方法返回与保存在 numString 中的数字值相等的整数。如果 numString 的前缀不能解释为整数,则返回 NaN(而不是数字)。
var num=[1,2,10,4,5,6,12,16,7]; var newNum=num.map(parseInt); // [1, NaN, 2, NaN, NaN, NaN, 8, 13, 7]
parseInt(10,2);// 2 parseInt('0xffffff',16); //16777215 parseInt(7,8); //7 parseInt(2,10);//2
目前,最新的浏览器,NodeList类数组也不支持map()方法,但是还是可以利用call()方法实现。
obj1.(method).call(obj2,argument1,argument2)
call()方法就是把obj1的方法拿给obj2用。argument是obj1方法的参数。
<label><input type="checkbox" name="hobby" id="c1" value="编程">编程</label> <label></label><input type="checkbox" name="hobby" id="c2" checked value="美术">美术</label> <label></label><input type="checkbox" name="hobby" id="c3" checked value="阅读">阅读</label> <script> var oCheckbox=document.querySelectorAll("input:checked"); //NodeList(2) [input#c2, input#c3] var values=Array.prototype.map.call(oCheckbox,function(obj){ return obj.value; }) console.log(values); //["美术", "阅读"] </script>
这里有个动图很好的解释了map()的工作原理,来源于:https://www.w3cplus.com/web/web-tips-15.html
3、filter()
filter是过滤,筛选的意思,顾名思义,应该是数组元素挨个进行某个条件测试,然后返回成功通过的新数组。
var newArray = arr.filter(callback(element[, index[, array]])[,thisArg])
callback
用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。
后面的参数和前面的map()等迭代函数意思一样。
返回值是一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。
var age=[12,18,25,45,60,17,22]; var result=age.filter(function(value){ return value>=18 && value<=45; }) console.log(result); //[18, 25, 45, 22]
var arr=[2,8,'a','12',-12,null,undefined,,'',NaN]; function myFilter(value){ return value!==undefined&&typeof(value)==='number'&&!isNaN(value)&&value!==0; } var newArr=arr.filter(myFilter); console.log(newArr); // [2, 8, -12]
4、every()
检测数组内所有元素是否通过测试,全部通过返回true,任何一个不通过,返回false。如果是一个空数组,返回true。返回布尔值。
感觉就是一竿子打翻一船人啊,或者说一颗老鼠屎坏了一锅汤 :)
function isBig(value) { return value >= 60 && value <= 100; } var result = [85, 75, 98, 53, 60, 105].every(isBig); console.log(result); //false 也可以简写成箭头函数: [85, 75, 98, 53, 60, 105].every(value=>value>=60&&value<=100)
5、some()
有至少一个数组元素通过了测试,就返回true。返回的是一个布尔值。
如果一个元素满足条件,返回true,且后面的元素不再被检测
所有元素都不满足条件,则返回false
不会改变原始数组
不会对空数组进行检测;数组为空的话,直接返回false
function isBiggerThan10(item){ return item>10; } [12,10,8,7,-5].some(isBiggerThan10); //true;
检查某个元素是否存在:
var myname=['老赵','小何','小王']; function isExit(arr,val){ return arr.some(function(value){ return value===val; }) } console.log(isExit(myname,'老赵')); //true
6、includes()
确定数组的条目中是否包含某个值,并根据需要返回true或false。没有回调函数,只有两个参数。
ES6的新方法,Edge14及以上才支持。
arr.includes(valueToFind[,fromIndex])
注意:比较字符的时候,区分大小写。
[1, 2, 3].includes(2); // true [1, 2, 3].includes(4); // false [1, 2, 3].includes(3, 3); // false [1, 2, 3].includes(3, -1); // true [1, 2, 3].includes(3, -4); // true [1, 2, NaN].includes(NaN); // true
该方法的第二个参数表示搜索的起始位置,默认为0。
如果fromIndex大于或等于数组的长度,则返回false。将不搜索数组。
如果FromIndex为负数,则按照array.length + fromIndex先计算。计算出的索引将用作数组中开始搜索valueToFind的位置。如果计算的索引小于或等于-1*array.length,则将搜索整个数组。
// array length is 3 // fromIndex is -100// computed index is 3 + (-100) = -97 var arr = ['a', 'b', 'c']; arr.includes('a', -100); // true arr.includes('b', -100); // true arr.includes('c', -100); // true arr.includes('a', -2); // false
以前查找使用indexOf(),但是不能判断出NaN。
[NaN].indexOf(NaN);// -1
现在includes()使用samevaluezero算法来确定是否找到给定的元素。所以可以得到NaN,而且+0,-0,0都当成0,false不能当成0。
[NaN].includes(NaN);// true [-0].includes(0);// true
如果为了兼容IE9,可以利用some()写一个includes()的简易版。
const contains = (() => Array.prototype.includes ? (arr, value) => arr.includes(value) : (arr, value) => arr.some(el => el === value) )(); contains(['foo', 'bar'], 'baz'); // => false
7、find()
arr.find(callback(element[, index[, array]])[, thisArg])
找到第一个符合条件测试的元素,并返回值,如果没有找到,返回undefined.
Edge12及以上支持,IE9不支持。
const myArr=[1,2,3,4,5,6]; var v=myArr.find(value=>value>4); console.log(v);// 5 const myArr=[1,2,3,4,5,6]; var v=myArr.find(value=>value>40); console.log(v);// undefined
8、findIndex()
arr.findIndex(callback(element[, index[, array]])[, thisArg])
和find()相似,只不过返回的是第一个通过测试的元素的索引值。没有返回-1。
const students=[ { id:1, s_name:'小王' }, { id:2, s_name:'小赵' }, { id:3, s_name:'小李子' } ] var i=students.findIndex(value=>value.id==2); console.log(i); //1 var n=students.findIndex(value=>value.id==5); console.log(n); //-1
数组的方法太多了,有些方法具有相似的功能,但是还是要看几个关键点,功能有什么区别,参数是什么,返回的值是什么,有没有修改原数组等。只有关联起来理解才不会混乱。
var arr1=[NaN,undefined,null,2,0]; console.log(arr1.indexOf(NaN)); //-1 console.log(arr1.includes(NaN)); //true console.log(arr1.find(function(value){ //null return value===null; })); console.log(arr1.findIndex(function(value){ //1 return value===undefined; })) console.log(arr1.filter(function(value){ // [null, 2, 0] return value>=0; }))
9、reduce()
reduce() 方法对数组中的每个元素执行一个回调函数中提供的reducer函数(升序执行),将其结果汇总为单个返回值。
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
reducer 函数接收4个参数:
Accumulator (acc) (累计器) 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(初始值)。
Current Value (cur) (当前值) 数组中正在处理的元素。
Current Index (idx) (当前索引) 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则为1。
Source Array (src) (源数组) 调用reduce()的数组
reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
initialValue 可选 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
返回函数累计处理的结果.
回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。
注意:如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) { return accumulator + currentValue;}, 0); //6
var initialValue = 0;var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) { return accumulator + currentValue.x;},initialValue) console.log(sum) // logs 6
var flattened = [[0, 1], [2, 3], [4, 5]].reduce( function(a, b) { return a.concat(b); }, []); // flattened is [0, 1, 2, 3, 4, 5]
数组的方法实在太多,看图:
数组全部的方法:MDN:Array
发表评论:
◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。