浅谈JS数组中四种常用的API

1,913 阅读5分钟

在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入门教程

    新手一枚,欢迎指正。