
在JavaScript中,数组是一个特殊的变量,用于存储不同的元素。数组的使用场景非常多,平日学习中也涉及到很多数组的api/相关操作,对目前常用到的四个api( map(),forEach(),filter(),some() )的理解总结了一下。不足之处,请多多指教。
1. map
-
map: "映射" 强调数组每一项的一一对应的关系,对每个元素进行处理,并返回新的数组。(注:使用map时一定要return一个值,因为它的作用就是映射关系得出结果)
-
定义: 创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
-
注:map() 不会对空数组进行检测,也不会改变原始数组。
先来一个简单的栗子:
const arr = [1,2,3,4]; //求原数组的平方 const squreArr = arr.map(item => item * item) console.log(squreArr);
结果:
[1,4,9,16]
-
其中map() 的功能就是映射,一一对应,把数组的每一项变成新的一项,得出一组新的数组。
下面再扔一个栗子帮助理解
eg:
//抽象出一个数组 todo=[] ,把它映射成为 HTML的过程,用js来完成 let todo = [//创建一个数组 并列出要做的每一项 {text: 'eat', done: false}, {text: 'work', done: false} ] ul.innerHTML = todo.map(function(item,i) { // map foreach 强调的功能不一样 return ` <li> <input type="checkbox" id="todo${i}"> <label for="todo${i}">${item.text}</label> </li> ` //return `` 里面添加动态替换的内容,必须是字符串,不能给数组 }).join('');//拼接 '':空字符串 去掉数组里面默认的逗号
-
map(function(item,i,ret)中,map()里面接收的是一个函数,function里面有三个参数分别是
item: 表示数组里的每一项
i: 索引,表示在数组的第几项
ret:表示map里面的原数组,每次循环都一样的,不常用。
可以尝试输出console.log(item,i,ret)看下三个参数的效果:
-
这里想提一下上面出现的 join(), 数组转字符串,把数组中的所有元素通过指定的分隔符进行分隔放入一个字符串,返回生成的字符串。
链式调用join(),把数组里的 每一项变成/拼接成字符串,才符合HTML的要求,就能插到页面上 例如 把插入 < li >的数组变成字符串
// map = [ `<li></li>`, `<li></li>`] // join = <li></li><li></li>
另外举例说明一下join()的效果:
2. forEach
-
定义: 用于调用数组的每个元素,并将元素传递给回调函数。
-
语法: array.forEach(function(currentValue, index, arr), thisValue)
-
forEach() 遍历的范围在第一次调用 function 前就会确定。
调用 forEach 后添加到数组中的项不会被 function 访问到。
如果已经存在的值被改变,则传递给 function 的值是 forEach() 遍历到他们那一刻的值。
-
关于forEach()要注意的是:
无法中途退出循环,只能用return退出本次回调,进行下一次回调。
它总是返回 undefined值,即使你return了一个值。
eg:
let a = [1, 2, ,3]; // 最后第二个元素是空的,不会遍历(undefined、null会遍历) let obj = { name: 'OBKoro1' }; let result = a.forEach(function (value, index, array) { a[3] = '改变元素'; a.push('添加到尾端,不会被遍历') console.log(value, 'forEach传递的第一个参数'); // 分别打印 1 ,2 ,改变元素 console.log(this.name); // OBKoro1 打印三次 this绑定在obj对象上 // break; // break会报错 return value; // return只能结束本次回调 会执行下次回调 console.log('不会执行,因为return 会执行下一次循环回调') }, obj); console.log(result); // 即使return了一个值,也还是返回undefined
3. filter
-
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。 可以理解为:它可以 在数组中过滤你想要的或者不想要的东西
-
语法:array.filter(function(currentValue,index,arr), thisValue)
-
注意: filter() 不会对空数组进行检测,且不会改变原始数组。
-
filter()方法是对数据中的元素进行过滤,也就是说是不能修改原数组中的数据,只能读取原数组中的数据,function需要返回布尔值;为true的时候,对应的元素留下来;为false的时候,对应的元素过滤掉。
eg: 返回数组 ages 中所有元素都大于 18 的元素:
常规写法
const ages = [32,15,19,12]; const nums = []; for(let age of ages) { if (age >= 18) { nums.push(age); } } console.log(nums);
接下来看一个超级精简的方法, es6中的新写法filter()
const ages = [32,15,19,12]; const adultArr = ages.filter( age => age >= 18); console.log(adultArr);
输出结果为
[32,19]
array.filter 语义化的过滤功能 可读性提升,用两三行代码就解决,里面还涉及到箭头函数,可点击自行了解,这就是es6让代码更优雅的新写法 ,表述性好一些 。
4. some
-
some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
-
some() 方法会依次执行数组的每个元素:
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
-
注意: some() 不会对空数组进行检测,且不会改变原始数组。
eg:
const ages = [32,15,19,12]; onst adultPresent = ages.some(age => age >= 50);//数组里有一个满足需求 //console.log(adultPresent); const allOldEnough = ages.every(age => age >= 50);//数组里面每一项都满足需求 console.log(allOldEnough);
5. 补充
-
forEach()与 map()不同的是,它总是返回 undefined值,并且不可链式调用。
经常有人用map来遍历数组,可以但不推荐,每个api都有各自的功能,map强调的是对象映射,数组可以用forEach()来遍历。
什么情况下你不该使用map:
A)你不打算使用返回的新数组
B) 你没有从回调函数中返回值
如果你还希望深入的学习 Map,可以参考这里Array.prototype.map()
-
说一下前面提到的es6,在写代码的过程中,我们需要注意HTML的语义化,并且es6新引入的语法特性,让我们的代码简洁易懂,可读性提升,让代码更优雅,以上提到的forEach 也是其中之一,还有 some等,后面将继续深入学习。 可参考阮一峰的ES6入门教程。
新手一枚,欢迎指正。