JavaScript数组方法持续更新

JavaScript数组方法持续更新

作为 js 的重要一员,一定要好好了解一番,若有理解不到之处,还望不吝指教。

何为数组,是有序的集合。

一、如何判断是否是数组


  1. Array.isArray() 字面上的理解,是不是一个数组。

    let arr = []
    let str = '[]'
    Array.isArray(arr) // true
    Array.isArray(str) // false
    
  2. instanceof 是不是 Array 的实例。

    let arr = []
    let str = '[]'
    arr instanceof Array // true
    str instanceof Array // false
    
  3. constructor , 实例对象的隐式原型指向对象的构造函数。

    let arr = []
    arr.constructor === Array // true
    
  4. Object.prototype.toString.call(arr) === '[object Array]'

    let arr = []
    Object.prototype.toString.call(arr) === '[object Array]' // true
    

二、创建数组


  • 字面量

    let arr = []
    
  • new Array()

    let arr = new Array()
    
  • split()

    let str = '1,2,3'
    let arr = str.split(',')
    
  • Array.from()

    // 将字符串转换成数组
    let str = '123'
    let arr = Array.from(str) // ["1","2","3"]
    
    // 将 arguments 伪数组转换为数组
    Array.from(arguments)
    
    // 将 dom 元素伪数组转换为数组
    Array.from(document.querySelectorAll('div'))
    

    Array.from 接受3个参数

    • 第一个参数必填,需要转换的对象
    • 第二个可选,接受一个回调函数,数组中的每一项都会回调该函数
    • 第三个可选,绑定回调函数的 this 指向
  • Array.of() 无论什么类型,包裹一层变成数组

    Array.of() 
    Array.of('') 
    Array.of(null)
    Array.of(undefined) 
    Array.of(NaN) 
    Array.of(()=>{}) 
    Array.of({}) 
    Array.of(123) 
    

三、数组的方法


关注一个方法或者函数,主要关注以下几点

  1. 参数
  2. 返回值

常用的数组方法

​ 不改变原数组

​ forEach map filter some every find findIndex concat indexOf lastindexOf slice flat includes

​ join reduce

​ 改变原数组

​ push unshift pop shift splice fill sort reverse

  • forEach()

    /*  接受 2 个参数
     *    第一个参数必填,回调函数
     *    第二个参数,绑定回调函数的 this 指向, (例子里的 obj)
     */
    Array.forEach( (item,index,Array) => {
      // item 表示数组当前循环到的项
      // index 表示数组当前循环项的下标值
      // Array 表示原数组
    },obj)
    

    forEach 不能中断循环(break),只能跳过当前循环项,进入下一项的循环。

    该方法返回值为 undefined

  • map() , 参数同 forEach 方法。

    // 不能直接跳出循环 break 会报错, return 也不行
    let arr = [1,2,3]
    let res = arr.map((item)=>{
     return item + 1
    })
    

    返回值为一个新的数组,不改变原来的数组。

  • filter(), 一般用来过滤数组中的元素,参数同 forEach 方法

    let obj = {}
    let arr = [
      {
        id: 1,
      },
      {
        id: 2,
      },
      {
        id: 3,
      },
    ]
    let newArr = arr.filter((item, index, Array) => {
      // 必须 return ,且新数组只会含有条件为 true 的项
      return item.id == 2
    }, obj)
    console.log(newArr) // [{id: 2}]
    

    返回值为一个新数组,不改变原数组

  • some() ,参数同 forEach

    arr.some( (item, index, Array) => {
       // 有一项满足条件,则返回 true ,剩余的项不在参与循环;没有满足条件,返回 false
       // 有点 逻辑 || 的意思,只是参与的项不同。
       return item.id === 2
    }, obj)
    

    返回值 Boolean 类型, true or false

  • every(),参数同 forEach

    /* 和 some() 方法相似,有一项是 false 则终止循环,返回 false,每一项都是 true ,返回 true
     * 这个完全和 && 的思想一致
     */
    

    返回值 Boolean 类型, true or false

    tips: 空数组是个特例,始终返回 true

  • find(),参数同 forEach

    /* 
     *  找到匹配的项则返回第一个匹配项,循环终止;找不到则返回 undefined
     */
    

    返回值,匹配的项 或者 undefined

  • findIndex(),参数同forEach

    // 匹配到选项则返回第一个匹配项的索引,循环终止,否则返回 -1
    

    返回值,匹配到的下标值 或者 -1

  • push()

    // 在数组的最后增加元素
    let arr = [1,2]
    arr.push(3) // 一个参数
    let res = arr.push(4,5,6) // 多个参数
    console.log(res) // [1, 2, 3, 4, 5, 6]
    console.log(arr) // 6
    

    返回数组的长度,并改变原数组

  • unshift()

    let arr = [1,2]
    arr.unshift(0) // 3
    

    返回数组的长度,并改变原数组

  • pop(), 不需要参数

    // 从数组的最后开始删除一个元素
    let arr = [1,2]
    arr.pop()  // 2
    

    返回被删除元素,空数组删除返回 undefined,改变原数组,

  • shift(), 不需要参数

    // 从数组的开头开始删除一个元素
    let arr = [1,2]
    arr.shift() // 1
    

    返回被删除元素,空数组删除返回 undefined,改变原数组,

  • concat(), 拼接数组

    let arr = [1, 2]
    let arr1 = [3, 4]
    let arr2 = [5, 6]
    let newArr = arr.concat(arr1, arr2) // 数组的拼接
    let newArr2 = newArr.concat() // 数组的浅拷贝
    

    返回值为新的数组, 不改变原来的数组

  • indexOf()lastIndexOf()

    // 找到第一次匹配元素的索引值,否则返回 -1
    let arr = [1,2,3,4]
    arr.indexOf(2, 0) // 从索引为 0 的位置开始向数组的末尾查找
    arr.lastIndexOf(2, arr.length-1) // 从索引为 arr.length-1 的位置开始向数组的开头查找
    

    返回值为匹配的下标 或者 -1

  • slice(), 浅拷贝数组

    let arr = [1,2,3,4,5,6]
    // 包含开始位置, 不包含结束位置
    arr.slice(1,2) // [2]
    

    返回值 新的数组, 不改变原数组

  • splice(), 万金油的存在,增、删、改功能。

    let arr = [1, 2, 3]
    
    /*  删除功能,任意位置删除
     *  参数1. 开始的索引位置,包含该位置
     *  参数2. 删除的个数
     *  返回值:返回删除的元素的一个数组,改变原数组
     */
    arr.splice(0, 1)  // [1]
    console.log(arr)  // [2, 3]
    
    /*  增加功能,任意位置增加元素
     *  参数1. 开始的索引位置,也可以理解为新数组的索引位置上插入新的项。
     *  参数2. 删除个数为 0
     *  参数3. 增加的项
     *  返回值:空数组,改变原数组
     */
    arr.splice(1, 0, 1, 2, 3)  // []
    console.log(arr)  // [2, 1, 2, 3, 3]
    
    /*  修改功能,任意位置修改,这个就是增加功能的变形
     *  参数1. 开始索引位置,包含该位置
     *  参数2. 替换的个数 n,包含从索引参数1开始在内的向后 n 项将会从数组去除
     *  参数3. 替换的项, 在数组索引参数1位置,向后插入替换的项
     *  返回值: 空数组,改变原数组
     */
    arr.splice(1, 2 ,{id:1},{id:2})
    
    

    主要是参数的灵活运用,组成不同的功能,很实用。

  • copyWithin()

    /* 从数组内部替换自身项
     * 参数1. 替换元素开始的位置
     * 参数2. 从该索引开始复制数据,默认是0
     * 参数3. 复制数据结束的索引值,不包含该位置,默认到数组的结束
     * 返回值:修改后的新数组
     */
    let arr = [1, 2, 3, 4]
    arr.copyWithin(0,1,2) // [2,2,3,4]
    

    返回值为新的数组,改变原数组

  • fill()

    /*  填充数组
     *  参数1. 用来填充数组的值
     *  参数2. 起始索引值,默认是 0 
     *  参数3. 终止索引值,不包含该项,默认是数组的长度
     */
    let arr = []
    arr.fill(1, 0, 10) // 无法改变空数组,只能改变已有的项
    arr = [1, 2, 3, 4]
    arr.fill(5, 1 ,2) // [1,5,3,4]
    

    返回值为改变后的数组,改变原数组

  • flat()

    /*  多维数组变成一维数组
     *  参数 指定展开嵌套数组的深度,Infinity 表示任意深度
     *  不传可以去除数组中的空项
     *  返回值:新的的数组,不改变原数组
     */
    let arr = [1, 2, [3, 4]]
    arr.flat(1)   // [1, 2, 3, 4]
    
    let arr1 = [1, 2, 3, , ,4]
    arr1.flat() // [1, 2, 3, 4]
    

    返回值:新的的数组,不改变原数组

  • flatMap(),参数同 forEach

    /*  循环数组,每一项执行一个函数,最终执行以下flat()方法
     *  返回值:新的数组,不会改变原数组 
     */
    let arr = [1, 2]
    arr.flatMap( (item) => {
        [item, item * 2]
    }) // [1,2,2,4]
    

    flatMap 只能展开一层数组

  • includes()

    /*  判断数组是否含有某个指定的值
     *  参数1. 包含项
     *  参数2. 检索的开始位置,包含该位置
     *  返回值:包含返回 true , 不包含返回 false
     */
    console.log([1, 2, 3].includes(3));    // true
    console.log([1, 2, 3].includes(3, 3))  // false
    console.log([1, 2, 3].includes(3, 2))  // true
    

    也可用于字符串的检索,区分大小写

  • sort()

    /*  排序
     *  参数1. 
     *  参数2. 
     *  规则
     *    - 不传值,则是转化为字符串逐位比较 ASCII 大小
     *    - 接收一个函数,函数有个两个参数 a b
     *        若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
     *        若 a 等于 b,则返回 0。
     *        若 a 大于 b,则返回一个大于 0 的值。
     *  返回值:新的排序后的数组
     */
    let arr = [1,5,2,10]
    arr.sort((a, b) => {
        // a - b 返回值为正数,则交换两项的位置
        return a - b
    }) // [1,2,5,10] 从小到大
    arr.sort((a, b) => {
        return b - a
    }) // [10,5,2,1] 从大到小
    

    返回值为有序的新数组,改变原数组

  • reverse()

    let arr = [1, 2, 3]
    arr.reverse() // [3, 2, 1]
    

    反转数组,改变原数组

  • toLocaleString()toString()

    /*  将数组的每一项使用 toLocaleString 或者 toString
     *  不同点是语言环境的不同
     *  返回值:字符串,不改变原数组
     */
    let arr = [1, 'a', { id: 1 }, new Date()]
    // 1,a,[object Object],2020/5/22 下午2:44:40
    console.log(arr.toLocaleString())
    // 1,a,[object Object],Fri May 22 2020 14:44:40 GMT+0800 (中国标准时间)
    console.log(arr.toString())
    

    返回值:字符串,不改变原数组

  • join()

    /*  将数组使用特定的符号进行分割
     *  返回值:字符串,不改变原数组
     */
    let arr = [1, 2, 3]
    arr.join() // 1,2,3
    arr.join('') //123
    arr.join('*') //1*2*3
    

    和 split 更配哦

  • reduce(), 实用且重要的方法。

    /*  累加和累计这种描述特贴切
     *  参数1. 一个处理函数,接收 4 个参数
     *      - pre 第一次为参数2的值,然后是每次 处理函数 返回的值
     *    — val 当前循环项
     *    - index 当前循环项索引
     *    — arr 当前数组
     *  参数2. 第一次 pre 的值,默认是数组的第一个值。
     */
    let str = '好好学习天天向上'
    let arr = str.split('')
    let i = 0
    let res = arr.reduce((pre, val, index, arr) => {
      console.log(i++)
      console.log(`pre:${pre}`)
      console.log(`val:${val}`)
      return pre + val
    }, '我会')
    console.log(res) // 我会好好学习天天向上
    

    返回值为累计的结果,不会改变原数组

  • reduceRight()

    和 reduce 的结果一样,不同的是从数组的最后开始。

参考


[ MDN ]:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array
[ 掘金 ]: https://juejin.im/post/5d1ff6def265da1b855c777f#heading-22

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。