最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 《javascript高级程序设计》学习笔记 | 6.2.Array

    正文概述 掘金(simon9124)   2021-03-19   386

    Array

    • ECMAScript 的数组是一组有序的数据(和其他语言相同),每个槽位可以存储任意类型的数据(和其他语言不同)
    • ECMAScript 的数组是动态大小的,随着数据添加而自动增长

    相关代码 →

    创建数组

    • 使用 Array 构造函数

      let colors = new Array()
      console.log(colors) // []
      
      • 给构造函数传入一个参数:若参数是数值,则 length 属性会被自动创建并设置为这个值;若参数不是数值,则创建只包含该参数的数组
      colors = new Array(10)
      console.log(colors) // [ <10 empty items> ]
      colors = new Array(true)
      console.log(colors) // [ true ]
      
      • 给构造函数传入多个参数,会自动创建包含这些参数的数组
      colors = new Array('red', 'blue')
      console.log(colors) // [ 'red', 'blue' ]
      
      • 可以省略 new 操作符,结果不变
      colors = Array(5)
      console.log(colors) // [ <5 empty items> ]
      
    • 使用数组字面量表示法(同对象字面量表示法,使用数组字面量表示法创建数组时,不会调用 Array 构造函数

    colors = ['red', 'blue', 3]
    colors = []
    
    • ES6 新增 Array.from(),将类数组结构转换为数组实例

      • 第一个参数是一个类数组对象,即任何可迭代结构或者包含 length 属性和可索引元素的结构
      console.log(Array.from('Matt')) // [ 'M', 'a', 't', 't' ],字符串被拆分为单字符数组
      
      console.log(Array.from(new Map().set(1, 2).set(3, 4))) // [ [ 1, 2 ], [ 3, 4 ] ],集合和映射转换为数组
      console.log(Array.from(new Set().add(1).add(2).add(3).add(4))) // [ 1, 2, 3, 4 ],集合和映射转换为数组
      
      const a1 = [1, 2, 3, 4]
      const a2 = Array.from(a1) // 浅拷贝,a2与a1引用不同的基对象
      console.log(a2) // [ 1, 2, 3, 4 ]
      console.log(a1 === a2) // false
      const a3 = a1 // a3与a1引用同一个基对象
      console.log(a1 === a3) // true
      
      const iter = {
        *[Symbol.iterator]() {
          yield 1
          yield 2
          yield 3
          yield 4
        },
      }
      console.log(Array.from(iter)) // [ 1, 2, 3, 4 ],可迭代对象转换为数组
      
      function getColors() {
        console.log(Array.prototype.slice.call(arguments)) // [ 'red', 'blue' ],将argumens对象转换为数组
        console.log(Array.from(arguments)) // [ 'red', 'blue' ],将argumens对象转换为数组
      }
      getColors('red', 'blue')
      
      const arrayLikeObject = {
        0: 1,
        1: 2,
        2: 3,
        3: 4,
        length: 4,
      }
      console.log(Array.from(arrayLikeObject)) // [ 1, 2, 3, 4 ],带有必要属性的自定义对象转换为数组
      
      • 第二个可选参数是一个映射函数,可直接增强新数组的值
      const a4 = Array.from(
        a1,
        (x) => x + 2 // 第二个可选参数:映射函数,增强数组
      ) // 增强新数组a4的值
      console.log(a4) // [ 3, 4, 5, 6 ]
      
      • 第三个可选参数是一个对象,用于指定映射函数中 this 的值此时映射函数不要用箭头函数
      const a5 = Array.from(
        a1,
        function (x) {
          console.log(this) // { exponent: 2 },第三个参数中指定this的值,此时不可用箭头函数
          return x ** this.exponent
        },
        { exponent: 2 } // 第三个可选参数:指定映射函数中this的值
      )
      console.log(a5) // [ 1, 4, 9, 16 ]
      
      const a6 = Array.from(a1, (x) => x ** this.exponent, { exponent: 2 }) // 如使用箭头函数
      console.log(a6) // [ NaN, NaN, NaN, NaN ]
      const a7 = Array.from(a1, (x) => this, { exponent: 2 }) // 因为用箭头函数,this的值是空对象
      console.log(a7) // [ {}, {}, {}, {} ]
      
    • ES6 新增Array.of(),将一组参数转换为数组

    console.log(Array.of(1, 2, 3, 4)) // [ 1, 2, 3, 4 ],将参数转换为数组
    console.log(Array.of(undefined, null)) // [ undefined, null ],将参数转换为数组
    
    创建数组语法参数
    构造函数let arr = new Array(3)单个数值/单个非数值/多个数组字面量let arr = ['red','blue']Array.from()Array.from('Matt')① 类数组对象 ② 映射函数 ③ 指定映射函数 this 值的对象Array.of()Array.of(1, 2, 3, 4)一组参数

    数组空位

    • 使用数组字面量初始化数组时,可以使用一串逗号创建空位
    let options = [, , , , ,] // 创建包含5个元素的数组
    console.log(options.length) // 5
    console.log(options) // [ <5 empty items> ]
    
    • 与之前的版本不同,ES6 新增的方法普遍将这些空位当成 undefined 元素
    options = [1, , , , 5]
    console.log(options) // [ 1, <3 empty items>, 5 ]
    
    // es6的for-of语句
    for (const option of options) {
      console.log(option === undefined)
      /*
        false
        true
        true
        true
        false
      */
    }
    
    // es6的for-of语句+entries()方法
    for (const [index, value] of options.entries()) {
      console.log(value)
      /*
        1
        undefined
        undefined
        undefined
        5
      */
    }
    
    console.log([, , ,]) // [ <3 empty items> ]
    // es6的Array.from()方法
    console.log(Array.from([, , ,])) // [ undefined, undefined, undefined ]
    // es6的Array.of()方法
    console.log(Array.of(...[, , ,])) // [(undefined, undefined, undefined)]
    
    • ES6 之前的方法会忽略这个空位,但具体行为也因方法而已
    console.log(options.map(() => 6)) // [ 6, <3 empty items>, 6 ],map会跳过空位置
    console.log(options.join('-')) // '1----5',join视空位置为空字符串
    
    • 由于行为不一致存在性能隐患,实践中尽量避免使用数组空位,如确实需要,可以显示地用 undefined 代替

    数组索引

    • 使用中括号并提供相应值的数字索引,可取得或设置数组的值
      • 索引小于数组包含的元素数,则返回存储在相应位置的元素
      • 索引大于等于包含的元素书,则数组长度自动扩展到该索引值加 1(若中间还有元素,则自动用 undefined 填充)
    colors = ['red', 'blue', 'green']
    console.log(colors[0]) // 'red',数组第1项
    colors[2] = 'black' // 设置数组第3项,重设数组原有的值
    console.log(colors) // [ 'red', 'blue', 'black' ]
    colors[3] = 'brown' // 设置数组第4项,扩展数组
    console.log(colors) // [ 'red', 'blue', 'black', 'brown' ]
    
    • 数组中元素的数量保存在length属性中,始终返回 0 或大于 0 的值
    console.log(colors.length) // 4,数组的长度是4
    
    • 通过修改数组的length属性,可以从数组末尾删除或添加元素
      • length值设置为小于数组元素数的值,则只保留数组前length位元素,剩余的末尾元素将被删除
      • length值设置为大于数组元素数的值,则新添加的元素都将以undefined填充
    colors.length = 3 // 将数组的长度设置为3,自动删除末尾'brown'
    console.log(colors[3]) // undefined
    colors.length = 5 // 将数组长度设置为5,新添加的元素以undefined填充
    console.log(colors[5]) // undefined
    
    • 使用length属性可以方便地向数组末尾添加元素
    colors = ['red', 'blue', 'green']
    colors[colors.length] = 'black' // 向数组末尾添加'black'
    colors[colors.length] = 'brown' // 向数组末尾添加'brown'
    console.log(colors) // [ 'red', 'blue', 'green', 'black', 'brown' ]
    

    检测数组

    检测数组适用情况
    instanceof只有一个全局作用域(只有一个网页/没有额外的 iframe)Array.isArray()任何时候(不用考虑在哪个全局上下文),首选

    迭代器方法

    • ES6 在 Array 原型上暴露了 3 个检索数组内容的方法:keys()values()entries()
      • keys()返回数组索引的迭代器
      • values()返回数组元素的迭代器
      • entries()返回索引/值对的迭代器
    colors = ['red', 'blue', 'green']
    console.log(Array.from(colors.keys())) // [ 0, 1, 2 ]
    console.log(Array.from(colors.values())) // [ 'red', 'blue', 'green' ]
    console.log(Array.from(colors.entries())) // [ [ 0, 'red' ], [ 1, 'blue' ], [ 2, 'green' ] ]
    
    • 使用 ES6 的解构,在循环中拆分键/值对
    for (const [i, el] of colors.entries()) {
      console.log(i)
      console.log(el)
      /* 
        0
        red
        1
        blue
        2
        green
      */
    }
    
    迭代器方法返回值
    keys()数组索引的迭代器values()数组元素的迭代器entries()索引/值对的迭代器

    复制和填充方法

    • ES6 新增填充数组方法fill(),在指定范围内(包含开始索引,不包含结束索引),向已有数组中插入全部或部分相同的值,不改变原数组大小
      • 参数一:要插入的值,非必填,若不填自动转为 undefined
      • 参数二:开始索引(包含),非必填,若不填则全部填充;若负数则想象成数组长度加上这个值
      • 参数三:结束索引(不包含),非必填,若不填则一直填充到数组末尾;若负数则想象成数组长度加上这个值
    let zeros = [0, 0, 0, 0, 0]
    
    zeros.fill(5) // 用5填充整个数组,省略了开始索引和结束索引
    console.log(zeros) // [ 5, 5, 5, 5, 5 ]
    zeros.fill(0) // 重置
    
    zeros.fill(6, 3) // 用6填充索引大于等于3的元素,省略了结束索引
    console.log(zeros) // [ 0, 0, 0, 6, 6 ]
    zeros.fill(0) // 重置
    
    zeros.fill(7, 1, 3) // 用7填充索引值大于等于1且小于3的元素
    console.log(zeros) // [ 0, 7, 7, 0, 0 ]
    zeros.fill(0) // 重置
    
    zeros.fill(8, -4, 3) // 相当于zeros.fill(8, 5-4, 3),用8填充索引值大于等于1且小于3的元素
    console.log(zeros) // [ 0, 8, 8, 0, 0 ]
    zeros.fill(0) // 重置
    
    • fill()静默忽略:超出数组边界、零长度、索引范围方向相反,若索引部分可用则填充可用部分
    zeros.fill(1, -10, -6) // 相当于zeros.fill(1, 5-10, 5-6),超出数组边界,忽略
    console.log(zeros) // [ 0, 0, 0, 0, 0 ]
    zeros.fill(0) // 重置
    
    zeros.fill(1, 10, 15) // 超出数组边界,忽略
    console.log(zeros) // [ 0, 0, 0, 0, 0 ]
    zeros.fill(0) // 重置
    
    zeros.fill(2, 4, 2) // 索引反向,忽略
    console.log(zeros) // [ 0, 0, 0, 0, 0 ]
    zeros.fill(0) // 重置
    
    zeros.fill(4, 3, 10) // 索引部分可用,填充可用部分
    console.log(zeros) // [ 0, 0, 0, 4, 4 ]
    zeros.fill(0) // 重置
    
    • ES6 新增批量复制方法copyWithin(),在指定范围内(包含开始索引,不包含结束索引),浅复制数组中的部分内容,并将复制内容从指定索引开始替换,不改变原数组大小
      • 参数一:从该索引开始替换,必填
      • 参数二:开始索引(包含),非必填,若不填则默认为 0;若负数则想象成数组长度加上这个值
      • 参数三:结束索引(不包含),非必填,若不填则一直填充到数组末尾;若负数则想象成数组长度加上这个值
    zeros = [1, 2, 3, 4, 5]
    
    zeros.copyWithin(2) // 浅复制整个数组,从索引为2开始替换(直到数组边界),省略了开始索引和结束索引
    console.log(zeros) // [ 1, 2, 1, 2, 3 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    zeros.copyWithin(4, 3) // 浅复制索引大于等于3到数组结束的元素,从索引为4开始替换(直到数组边界),省略了结束索引
    console.log(zeros) // [ 1, 2, 3, 4, 4 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    zeros.copyWithin(3, 1, 3) // 浅复制索引大于等于1且小于3的元素,从索引为3开始替换(直到数组边界)
    console.log(zeros) // [ 1, 2, 3, 2, 3 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    zeros.copyWithin(2, -4, -1) // 相当于zeros.copyWithin(2, 5-4, 5-1),浅复制索引大于等于1且小于4的元素,从索引为2开始替换(直到数组边界)
    console.log(zeros) // [ 1, 2, 2, 3, 4 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    • fill()copyWithin()也会静默忽略:超出数组边界、零长度、索引范围方向相反,若索引部分可用则填充可用部分
    zeros.copyWithin(2, -15, -12) // 相当于zeros.copyWithin(2, 5-15, 5-12),超出数组边界,忽略
    console.log(zeros) // [ 1, 2, 3, 4, 5 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    zeros.copyWithin(2, 12, 15) // 超出数组边界,忽略
    console.log(zeros) // [ 1, 2, 3, 4, 5 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    zeros.copyWithin(2, 3, 1) // 索引反向,忽略
    console.log(zeros) // [ 1, 2, 3, 4, 5 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    zeros.copyWithin(2, 3, 6) // 索引部分可用,填充可用部分
    console.log(zeros) // [ 1, 2, 4, 5, 5 ]
    zeros = [1, 2, 3, 4, 5] // 重置
    
    复制和填充数组含义参数
    fill()指定范围内向数组插入相同的值① 要插入的值 ② 开始索引(包含) ③ 结束索引(不包含)copyWithin()浅复制数组指定范围内容,从指定索引开始替换① 从该索引开始替换 ② 开始索引(包含) ③ 结束索引(不包含)

    转换方法

    • 所有对象都有toLocaleString()toString()valueOf()方法:
      • valueOf()返回数组本身
      • toString()对数组每个值调用其toString()方法,返回由逗号分隔拼接而成的字符串
      • toLocaleString()对数组每个值调用其toLocaleString()方法,返回由逗号分隔拼接而成的字符串
    colors = ['red', 'blue', 'green']
    console.log(colors) // [ 'red', 'blue', 'green' ]
    console.log(colors.valueOf()) // [ 'red', 'blue', 'green' ]
    console.log(colors.toString()) // red,blue,green
    console.log(colors.toLocaleString()) // red,blue,green
    
    // toLocaleString() vs toString()
    let person1 = {
      toLocaleString() {
        return 'Nikalaos'
      },
      toString() {
        return 'Nicholas'
      },
    }
    let person2 = {
      toLocaleString() {
        return 'Grigorios'
      },
      toString() {
        return 'Greg'
      },
    }
    let people = [person1, person2]
    console.log(people.toString()) // Nicholas,Greg
    console.log(people.toLocaleString()) // Nikalaos,Grigorios
    
    • join()对数组每个值调用其toString()方法,接收一个参数作为设定数组返回拼接字符串的分隔符
    console.log(colors.join()) // red,blue,green,默认用逗号拼接
    console.log(colors.join(undefined)) // red,blue,green,默认用逗号拼接
    console.log(colors.join('|')) // red|blue|green
    console.log([undefined, 1, 2].join()) // ,1,2
    
    数组转换返回参数
    valueOf()数组本身toString()对每个值调用toString(),返回逗号拼接的字符串toLocaleString()对每个值调用toLocaleString(),返回逗号拼接的字符串join()对每个值调用toString(),返回指定分隔符拼接的字符串指定分隔符

    设定数组返回拼接字符串的分隔符

    栈方法

    • 栈是后进先出的结构,数据项的插入(push)和删除(pop)只在栈顶发生,ECMAScript 数组提供了push()pop()方法,以实现类似栈的行为

    • push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度

    colors = new Array()
    console.log(colors.push('red', 'blue')) //2,返回数组的长度
    
    • pop()方法用于删除数组的最后一项,返回被删除的项
    console.log(colors.pop()) // 'blue',返回被删除的项
    
    栈方法操作返回参数
    push()数组末尾添加项数组的最新长度要添加的项pop()删除数组最后一项被删除的项

    队列方法

    • 队列是先进先出的结构,对应的方法是shift()unshift()
    • shift()方法用于删除数组的开头一项,返回被删除的项
    colors = new Array()
    colors.push('red', 'blue')
    console.log(colors.shift()) // 'red',返回被删除的项
    
    • unshift()方法接收任意数量的参数,并将它们添加到数组开头,返回数组的最新长度
    console.log(colors.unshift('green', 'black')) // 3,返回数组的长度
    console.log(colors) // [ 'green', 'black', 'blue' ]
    
    栈方法操作返回参数
    shift()删除数组开头一项被删除的项unshift()数组开头添加项数组的最新长度要添加的项

    排序方法

    • reverse()方法将数组元素反向排列
    let values = [1, 2, 3, 4, 5]
    values.reverse()
    console.log(values) // [ 5, 4, 3, 2, 1 ]
    
    • sort()方法会在每一项上调用String()转型函数,然后比较字符串按序重新排列数组元素(默认升序)
    values = [0, 1, 5, 10, 15]
    values.sort()
    console.log(values) // [ 0, 1, 10, 15, 5 ],比较字符串大小而不是数字大小
    
    • sort()方法可以接收一个比较函数,用于判断数组中数值的排列顺序,比较函数接收 2 个参数(以升序为例):

      • 如果第 1 个参数应该排在第二个参数前面,则返回负值
      • 如果 2 个参数相等,则返回 0
      • 如果第 1 个参数应该排在第二个参数后面,则返回正值
      function compareAsc(val1, val2) {
        if (val1 < val2) {
          return -1
        } else if (val1 > val2) {
          return 1
        } else {
          return 0
        }
      }
      values = [0, 1, 5, 10, 15]
      values.sort(compareAsc) // 接收参数:正序比较函数
      console.log(values) // [ 0, 1, 5, 10, 15 ]
      
      • 如果想产生降序效果,只需把比较函数的返回值交换
      function compareDesc(val1, val2) {
        if (val1 < val2) {
          return 1 // 降序
        } else if (val1 > val2) {
          return -1 // 降序
        } else {
          return 0
        }
      }
      values.sort(compareDesc) // 接收参数:降序比较函数
      console.log(values) // [ 15, 10, 5, 1, 0 ]
      
      • 比较函数可以简写为箭头函数
      values.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)) // 升序
      console.log(values) // [ 0, 1, 5, 10, 15 ]
      
      • 如果数组的元素是数值valueOf()方法返回数值的对象(如 Date 对象),比较函数可进一步简化为减法操作,用第 1 个参数减去第 2 个参数(或相反)
      values.sort((a, b) => a - b) // 升序
      console.log(values) // [ 0, 1, 5, 10, 15 ]
      values.sort((a, b) => b - a) // 降序
      console.log(values) // [ 15, 10, 5, 1, 0 ]
      
    排序方法操作返回参数
    reverse()数组元素反向排列调用数组的引用sort()数组元素按序排列调用数组的引用比较函数,用于判断排列顺序

    操作方法

    • concat()创建当前数组的副本,然后把它的参数添加到数组末尾,返回新构建的数组,不改变原数组
      • 若参数是一个或多个数组,则把这些数组的每一项都添加到结果数组末尾
      • 若参数不是数组,则直接把它们添加到结果数组末尾
    colors = ['red', 'green', 'blue']
    let colors2 = colors.concat('yellow', ['black', 'brown'])
    console.log(colors) // [ 'red', 'green', 'blue' ],不改变原数组
    console.log(colors2) // [ 'red', 'green', 'blue', 'yellow', 'black', 'brown' ]
    let colors3 = colors.concat('yellow', ['black', 'brown', ['orange']]) // [ 'red', 'green', 'blue', 'yellow', 'black', 'brown', [ 'orange' ] ]
    console.log(colors3)
    
    • 在参数数组上指定特殊的符号Symbol.isConcatSpreadable,设置为 false 可阻止打平数组(数组默认打平),设置为 true 可打平类数组对象(类数组对象默认不打平)
    let newColors = ['black', 'brown'] // 数组
    let moreNewColors = {
      // 类数组对象
      0: 'pink',
      1: 'cyan',
      length: 2,
    }
    console.log(colors.concat(newColors)) // [ 'red', 'green', 'blue', 'black', 'brown' ],数组默认打平
    console.log(colors.concat(moreNewColors)) // [ 'red', 'green', 'blue', { '0': 'pink', '1': 'cyan' } ],类数组对象默认不打平
    
    newColors[Symbol.isConcatSpreadable] = false // 阻止打平数组
    moreNewColors[Symbol.isConcatSpreadable] = true // 强制打平类数组对象
    
    console.log(colors.concat(newColors)) // [ 'red', 'green', 'blue',[ 'black', 'brown', [Symbol(Symbol.isConcatSpreadable)]: false] ]
    console.log(colors.concat(moreNewColors)) // [ 'red', 'green', 'blue', 'pink', 'cyan' ]
    
    • slice()创建一个包含原有数组中若干元素的新数组,不改变原数组,接收 1 个或 2 个参数(开始索引&结束索引)
      • 1 个参数,返回该索引到数组末尾的所有元素
      • 2 个参数,返回从开始索引到结束索引的所有元素,不包含结束索引
      • fill()copyWithin(),索引负值则以数组长度加上负值即可
    colors = ['red', 'green', 'blue', 'black', 'brown']
    console.log(colors.slice(1)) // [ 'green', 'blue', 'black', 'brown' ],索引大于等于1到末尾的元素
    console.log(colors.slice(1, 4)) // [ 'green', 'blue', 'black' ],索引大于等于1小于4的元素
    
    • splice()可在数组中插入元素、删除元素或同时进行插入和删除两种操作,返回被删除元素组成的数组改变原数组
      • 删除元素,传入 2 个参数:要操作元素的开始位置、要删除元素数量
      • 插入(并删除)元素,传入大于等于 3 个参数:要操作元素的开始位置、要删除元素数量(0 则不删除)、要插入的元素 1、要插入的元素 2...
    colors = ['red', 'green', 'blue']
    let removed = colors.splice(0, 1) // 从索引0开始,删除1项
    console.log(removed) // [ 'red' ],返回被删除元素组成的数组
    console.log(colors) // [ 'green', 'blue' ],改变原数组
    
    removed = colors.splice(1, 0, 'yellow', 'orange') // 从索引1开始,删除0项,插入'yellow'、'orange'
    console.log(removed) // [],没有被删除的元素
    console.log(colors) // [ 'green', 'yellow', 'orange', 'blue' ]
    
    removed = colors.splice(1, 1, 'black', 'purple') // 从索引1开始,删除1项,插入'black'、'purple'
    console.log(removed) // [ 'yellow' ]
    console.log(colors) // [ 'green', 'black', 'purple', 'orange', 'blue' ]
    
    操作方法操作返回参数改变原数组
    concat()数组末尾追加元素新数组要添加的元素/数组slice()创建包含原数组若干元素的新数组新数组① 开始索引 ② 结束索引(不包含)splice()数组(同时)插入元素、删除元素被删除元素组成的数组① 开始索引 ② 要删除个数 ③ 插入元素 1 ④ 插入元素 2

    搜索和位置方法

    • ECMASctipr 提供 2 类搜索数组的方法:严格相等搜索和断言函数搜索

    严格相等

    • 3 个方法:indexOf()lastIndexOf()includes()
      • 均接收 2 个参数:要查找的元素(必填)、起始搜索位置(非必填)
      • indexOf()includes()从前向后搜索,lastIndexOf()从后向前搜索
      • indexOf()lastIndexOf()返回要查找元素首次出现的位置(无匹配返回-1),includes()返回布尔值
      • 查找时,均使用 === 全等比较
      • includes()是 ES7 新增的方法
    let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]
    
    console.log(numbers.indexOf(4)) // 3,从前向后,数组首次出现4的索引
    console.log(numbers.lastIndexOf(4)) // 5,从后向前,数组首次出现4的索引
    console.log(numbers.includes(4)) // true,从前向后,数组中是否包含4
    
    console.log(numbers.indexOf(4, 4)) // 5,从前向后,从数组索引4开始首次出现4的索引
    console.log(numbers.lastIndexOf(4, 4)) // 3,从后向前,从数组索引4开始首次出现4的索引
    console.log(numbers.includes(4, 7)) // false,从前向后,从数组索引7开始是否包含4
    
    let man = { name: 'Nicholas' }
    let human = [{ name: 'Nicholas' }] // 不全等,human数组中的对象和对象man来自不同的引用
    let human2 = [man] // 全等,将对象man放入human2数组
    
    console.log(human.indexOf(man)) // -1
    console.log(human2.indexOf(man)) // 0
    console.log(human.includes(man)) // false
    console.log(human2.includes(man)) // true
    
    严格相等参数查找顺序返回
    indexOf()① 要查找元素(必) ② 起始搜索位置(非)前 → 后要查找元素首次出现的位置,无匹配返回-1lastIndexOf()① 要查找元素(必) ② 起始搜索位置(非)后 → 前要查找元素首次出现的位置,无匹配返回-1includes()① 要查找元素(必) ② 起始搜索位置(非)前 → 后布尔值

    断言函数

    • 2 个方法:find()findIndex()
      • 均接收 2 个参数:断言函数、指定断言函数内部 this 的值(可选)
      • 断言函数又接收 3 个参数:元素、索引、数组本身
      • find()返回第一个匹配的元素,无匹配返回 undefined
      • findIndex()返回第一个匹配元素的索引,无匹配返回-1
    people = [
      { name: 'Matt', age: 27 },
      { name: 'Nicholas', age: 29 },
    ]
    console.log(people.find((e, i, arr) => e.age > 28)) // { name: 'Nicholas', age: 29 },返回元素
    console.log(people.findIndex((e, i, arr) => e.age > 28)) // 1,返回索引
    console.log(people.find((e, i, arr) => e.age > 30)) // undefined,无匹配
    console.log(people.findIndex((e, i, arr) => e.age > 30)) // -1,无匹配
    
    • 一旦找到匹配项,两个方法均不再继续搜索
    numbers = [3, 6, 9]
    numbers.find((e, i, arr) => {
      console.log(e)
      console.log(i)
      console.log(arr)
      return e % 2 === 0 // 匹配条件:元素能被2整除
      /* 
        开始搜索:
        3,不符合匹配条件
        0,此时的索引
        [ 3, 6, 9 ],此时的数组
    
        继续搜索:
        6,符合匹配条件
        1,此时的索引
        [ 3, 6, 9 ],次数的数组
        
        不再继续搜索
      */
    })
    
    断言函数参数返回
    find()① 断言函数(必) ② 指定断言函数内部 this 的值(非)第一个匹配的元素,无匹配返回 undefinedfindIndex()① 断言函数(必) ② 指定断言函数内部 this 的值(非)第一个匹配元素的索引,无匹配返回-1

    迭代方法

    • 5 个方法every()some()filter()map()forEach()
    • 每个方法接收 2 个参数:以每一项为参数运行的函数、作为函数运行上下文的作用域对象(非必填,影响函数中 this 的值)
    • 传给每个方法的函数接收 3 个参数:元素、索引、数组本身
      • every():对数组每一项运行传入的函数,若每项都返回 true,则该方法返回 true
      • some():对数组每一项运行传入的函数,若有一项返回 true,则该方法返回 true
      • filter():对数组每一项运行传入的函数,由返回 true 的项组成数组,返回给该方法
      • map():对数组每一项运行传入的函数,由每项调用的结果组成数组,返回给该方法
      • forEach():对数组每一项运行传入的函数,相当于使用 for 循环遍历数组,该方法没有返回值
      • 除了forEach(),其他 4 种方法的参数运行函数都必须有 return(或取消大括号的箭头函数)
    numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]
    
    // some()
    let everyResult = numbers.every((item, index, array) => item > 2) // 是否每项都大于2
    console.log(everyResult) // false
    
    let someResult = numbers.some((item, index, array) => item > 2) // 是否有1项大于2
    console.log(someResult) // true
    
    // filter()
    let filterResult = numbers.filter((item, index, array) => item > 2) // 筛选出大于2的元素
    console.log(filterResult) // [ 3, 4, 5, 4, 3 ]
    
    // map()
    let mapResult = numbers.map((item, index, array) => item * 2) // 返回每项调用函数的结果
    console.log(mapResult) // [ 2, 4, 6, 8, 10, 8, 6, 4, 2 ]
    
    // forEach()
    let forEachResult = numbers.forEach((item, index, array) => {
      item = item * 2
    })
    console.log(forEachResult) // undefined,forEach没有返回值
    numbers.forEach((item, index, array) => {
      // 在函数内执行操作,相当于使用for循环遍历
      console.log(item * 2)
      /* 
        2
        4
        6
        8
        10
        8
        6
        4
        2 
      */
    })
    
    迭代方法参数返回
    every()① 运行函数(必),必须有返回值 ② 函数的作用域对象(非)每项运行参数函数,每项都返回 true 方法才返回 truesome()① 运行函数(必),必须有返回值 ② 函数的作用域对象(非)每项运行参数函数,有一项返回 true 方法就返回 truefilter()① 运行函数(必),必须有返回值 ② 函数的作用域对象(非)每项运行参数函数,返回 由返回 true 的项组成的数组map()① 运行函数(必),必须有返回值 ② 函数的作用域对象(非)每项运行参数函数,返回 由每项调用的结果组成的数组forEach()① 运行函数(必),没有返回值 ② 函数的作用域对象(非)无返回值

    归并方法

    • 2 个方法reduce()reduceRight(),均迭代数组的所有项,在此基础上构建一个最终返回值
    • 每个方法接收 2 个参数:对每一项都会运行的归并函数、归并起点的初始值(非必填)
    • 每个归并函数接收 4 个参数:上一个归并值、当前项、当前索引、数组本身
    • 若省略归并起点值,则首次迭代将从数组第 2 项开始,传给归并函数的第 1 个参数是数组第 1 项,第 2 个参数是数组第 2 项
    • reduce()从前向后遍历,reduceRight()反之
    values = [1, 2, 3, 4, 5]
    
    // reduce()
    let sum1 = values.reduce((pre, cur, index, arr) => {
      console.log(pre, cur, index)
      /* 
        1 2 1
        3 3 2
        6 4 3
        10 5 4
      */
      return pre + cur
    }) // 省略归并起点值,归并函数第1个参数为数组第2项,第2个参数为数组第2项
    console.log(sum1) // 15
    
    let sum2 = values.reduce((pre, cur, index, arr) => {
      console.log(pre, cur, index)
      /* 
        10 1 0
        11 2 1
        13 3 2
        16 4 3
        20 5 4
      */
      return pre + cur
    }, 10) // 归并起点值为10,归并函数第1个参数为10,第2个参数为数组第1项
    console.log(sum2) // 25
    
    // reduceRight
    let sum3 = values.reduceRight((pre, cur, index, arr) => {
      console.log(pre, cur, index)
      /* 
        5 4 3
        9 3 2
        12 2 1
        14 1 0
      */
      return pre + cur
    })
    console.log(sum3) // 15
    
    let sum4 = values.reduceRight((pre, cur, index, arr) => {
      console.log(pre, cur, index)
      /* 
        10 5 4
        15 4 3
        19 3 2
        22 2 1
        24 1 0
      */
      return pre + cur
    }, 10) // 归并起点值为10,归并函数第1个参数为10,第2个参数为数组最后1项
    console.log(sum4) // 25
    
    迭代方法参数遍历方向返回
    reduce()① 归并函数(必) ② 归并起点值(非)前 → 后遍历后最终返回值reduceRight()① 运行函数(必) ② 归并起点值(非)后 → 前遍历后最终返回值

    总结 & 问点

    • 有哪些基本方法可以创建数组?如何将类数组或一组参数转换为数组实例?
    • 为什么不建议使用数组空位?如果确实需要呢?
    • 数组的 length 属性是可变的么?如何快速的向数组末尾添加元素?
    • 如何判断一个对象是不是数组?
    • 用什么方法获取数组索引组成的数组?元素和键值对呢?
    • 用什么方法批量填充数组的部分内容?用什么方法获取数组每个值拼接的字符串?若指定分隔符呢?
    • 数组的“栈方法”和“队列方法”分别是怎样的用法和返回值?
    • 如何按照升序/降序排列数组元素?如果数组元素是数值,如何简化写法?
    • 如何将数组和类数组对象打平后添加到另一个数组的末尾?不打平添加呢?
    • 请详述 slice()和 splice()的含义、用法、返回值及是否改变原数组
    • 有哪些方法可以搜索数组?请分别详述其用法并举例
    • 有哪些数组迭代方法?请分别详述其用法并举例
    • 有哪些数组归并方法?请分别详述其用法并举例

    起源地下载网 » 《javascript高级程序设计》学习笔记 | 6.2.Array

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元