数组,对象操作相关

数组

数组操作方法

  • Establish方法–’创建数组’
  • Mutator方法–’突变方法’–改变原数组
  • Accessor方法–’访问方法’–不改变原数组
  • Iteration方法–’遍历方法’

Establish(创建数组的方式)

字面量,构造器方法
1
2
3
let arr = [1,2,3]
let arr = new Array(2) // [empty*2] 只有一个数字时表示数组长度,长度为2的空数组
let arr = Array(1,2,3) // [1,2,3] Array同new Array
es6方法
  • Array.of()
    解决上述构造器方法参数个数不同导致的行为差异
    1
    2
    3
    4
    5
    6
    7
    let arr = Array.of()   // []
    let arr = Array.of(1) // [1]
    let arr = Array.of(1,2,3) // [1,2,3]
    // 兼容实现
    Array.of = function () {
    return Array.prorotype.slice.call(arguments) // 指向arguments对象
    }
  • Array.from(arrayLike[, mapFn[, thisArg]])
    从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
    • arrayLike
      想要转换成数组的伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)或可迭代对象(可以获取对象中的元素,如 Map和 Set 等)。
    • mapFn 可选
      如果指定了该参数,新数组中的每个元素会执行该回调函数。
    • thisArg 可选
      可选参数,执行回调函数 mapFn 时 this 对象。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      let str = 'asd'
      let a = Array.from(str)
      console.log(a); // [ 'a', 's', 'd' ]

      let baseArr = [1,2,3,4]
      let arr = Array.from(baseArr, item => item*2)
      console.log(arr); // [ 2, 4, 6, 8 ]
      let obj = {
      controlItem (item) {
      return item * 3
      }
      }
      let arr2 = Array.from(baseArr, function (item) { return this.controlItem(item) }, obj)
      console.log(arr2); // [ 3, 6, 9, 12 ]

      let arrObj = { // 类数组对象
      'a': 0, // 非索引属性
      1: 1, // 索引属性
      3: 3, // 索引值排序混乱也会按正常索引顺序
      2: 2,
      4: {a: 1},
      6: 6, // 索引值与length不符
      length: 6 // 必须有length,没有会转出[]
      }
      console.log(Array.from(arrObj)); // [ undefined, 1, 2, 3, { a: 1 }, undefined ]
      let copyArr = Array.from(arrObj) // 浅拷贝,影响源数据
      copyArr[4].a = 'a' // [ undefined, 1, 2, 3, { a: 'a' }, undefined ]
      console.log(copyArr, arrObj); // { '1': 1, '2': 2, '3': 3, '4': { a: 'a' }, '6': 6, a: 0, length: 6 }

      Array.from.length // 1
      console.log(Array.from({length: 2})); // [ undefined, undefined ]
      console.log(Array.from({length: 2}, (item, i) => i)); // [ 0, 1 ]

      let map = new Map([['a',1],['b',2],['c',3]])
      console.log(map); // Map { 'a' => 1, 'b' => 2, 'c' => 3 }
      console.log(Array.from(map)); // [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
      console.log(Array.from(map.values())); // [ 1, 2, 3 ]
      console.log(Array.from(map.keys())); // [ 'a', 'b', 'c' ]

      let set = new Set([1,2,3,4])
      console.log(set);
      console.log(Array.from(set));
      console.log([...set]);

Mutator(突变方法)(改变原数组)

  • push: **+ | 传参(单个或多个) | 返回值(新数组长度)
  • unshift: +** | 传参(单个或多个) | 返回值(新数组长度)
  • pop: **- | 传参(无) | 返回值(被删除的元素)
  • shift: -** | 传参(无) | 返回值(被删除的元素)
    1
    2
    3
    4
    5
    6
    let arr = [1,2,3]
    let arr2 = [4,5,6]
    arr.push(arr2) // 4 合并后数组长度
    arr // [1,2,3,[4,5,6]]
    // 合并两个数组
    [].push.apply(arr,arr2) // [1,2,3,4,5,6] this指向arr,arr2被结构,依次push
  • reverse
    1
    2
    3
    let arr = [1,2,3]
    arr.reverse() // [3,2,1] 返回值即翻转后的数组
    arr // [3,2,1]
  • splice([idx[,length[,arguments]]])
    截取数组元素并返回并向原数组添加元素
    所有参数可选
    idx: 截取开始位置索引;负数表示从后算起
    length: 截取长度(不传表示最大长度);长度为0可实现向数组指定位置添加元素
    arguments: 向原数组添加的元素(添加位置是index)
    1
    2
    3
    4
    5
    6
    7
    let arr = [1,2,3]
    let s = arr.splice(1,1,4,5,6)
    s // [2]
    arr // [1,4,5,6,3]
    let s = arr.splice(1,0,4,5,6)
    s // []
    arr // [1,4,5,6,2,3] 在索引为1的位置插入元素
  • fill([value[,start[,end]]])
    用一个值填充(覆盖)数组索引start(包括)到end(不包括)的元素
    参数非必传,返回填充后数组
    value 要填充的值,不传会被填充为undefined
    start 开始索引,不传或非数字默认为0
    end 结束索引,不传为最大值
    1
    2
    3
    4
    5
    let arr = [1,2,3,4]
    arr.fill() // [undefined * 4]
    arr.fill('fill', 1, 2) // [1, 'fill', 3, 4]
    arr.fill(5) // [5, 5, 5, 5]
    let arr2 = new Array(3).fill(0) // [0,0,0]
  • sort([compareFunction(firstEl,secondEl)])
    排序并返回排序后数字
    参数可选,默认顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
    比较值小于0升序
    大于0降序
    等于0不变
    1
    2
    3
    let arr = [1,5,3,11,44,22]
    arr.sort() // [ 1, 11, 22, 3, 44, 5 ]
    arr.sort((a,b) => a-b) // [ 1, 3, 5, 11, 22, 44 ]
  • copyWithin(target[, start[, end]])
    1
    2
    3
    4
    5
    6
    7
    浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
    let arr = ['a','b','c','d','e','f']
    arr.copyWithin() // [ 'a', 'b', 'c', 'd', 'e', 'f' ]
    arr.copyWithin(1,2,3) // [ 'a', 'c', 'c', 'd', 'e', 'f' ]
    arr.copyWithin(1,2) // [ 'a', 'c', 'd', 'e', 'f', 'f' ]
    arr.copyWithin(2,1) // [ 'a', 'b', 'b', 'c', 'd', 'e' ]
    // 长度不变,所以会覆盖,从target位置开始覆盖

Accessor(访问方法)(不改变原数组)

  • join
  • toString
  • concat
  • slice([start[,end]]) 包含start,不包含end
    1
    2
    3
    4
    5
    let arr = [1,2,3]
    arr.join() === arr.toString()
    arr.slice() // [1,2,3]
    arr.slice(-2) // [2,3]
    arr.slice(0,1) // [1]
  • includes
  • indexOf(searchElement[, fromIndex])
  • lastIndexOf(searchElement[, fromIndex]) 查找指定元素在数组中的最后一个位置
    1
    2
    3
    4
    5
    6
    包括fromIndex
    let arr = [1,2,3,2,1]
    arr.indexOf(1, 1) // 4 从索引1开始向后找
    arr.lastIndexOf(2, 1) // 1 从索引1开始向前找
    arr.lastIndexOf(2, 2) // 1
    arr.lastIndexOf(2, 3) // 3
  • flat([depth]) 扁平化多维数组
    1
    2
    3
    4
    5
    6
    depth: 深度,默认1
    let arr = [1,2,[{a:1},4,[5,6]]]
    let arrFlat = arr.flat(Infinity) // 无穷大
    arrFlat[2].a = 2 // 浅拷贝
    console.log(arrFlat); // [ 1, 2, { a: 2 }, 4, 5, 6 ]
    console.log(arr); // [ 1, 2, [ { a: 2 }, 4, [ 5, 6 ] ] ]

Iteration(遍历方法)

带回调的遍历方法使用一下原则

  1. 对于空数组是不会执行回调函数的
  2. 对于已在迭代过程中删除的元素,或者空元素会跳过回调函数(for循环不会跳过,返回undefined)
  3. 遍历次数再第一次循环前就会确定,再添加到数组中的元素不会被遍历。
  4. 如果已经存在的值被改变,则传递给 callback 的值是遍历到他们那一刻的值。

  • forEach (cb(cur [, idx [, arr]])[, thisArg])
  • map (cb(cur [, idx [, arr]])[, thisArg])
  • filter (cb(cur [, idx [, arr]])[, thisArg])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    以上循环不能终止;
    forEach的返回值永远是undefined,不管你return什么,return只能跳过本次回调,不能结束循环

    let arr = [1,2,3,2,1]
    arr.forEach(item=> {
    if (item === 3){
    return
    }
    console.log(item); // 1 2 2 1
    })
  • every (cb(cur [, idx [, arr]])[, thisArg])
  • some (cb(cur [, idx [, arr]])[, thisArg])
  • find (cb(cur [, idx [, arr]])[, thisArg])
  • findIndex (cb(cur [, idx [, arr]])[, thisArg])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    以上循环不能终止,满足条件时会自动终止
    let arr = [1,2,3]
    let find = arr.find(item => { // 返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
    return item > 1
    })
    let findIndex = arr.findIndex(item => { // 返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
    return item > 1
    })
    // findIndex 1
  • reduce (cb(acc, cur[, idx[, arr]])[, initialValue])
  • reduceRight (cb(acc, cur[, idx[, arr]])[, initialValue])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    acc: 累加器(不指定初始值时,是第一个元素,数组对象形式必须指定初始值)
    cur: 当前元素值
    initialValue: 初始值
    注: 不指定初始值时,idx从1开始,指定时从0开始
    不指定初始值时,空数组报错
    不指定初始值并且数组只有一个元素或指定初始值但空数组,直接返回值,不走cb函数
    reduceRight同上,从数组右侧开始,不指定初始值时,idx从length-2开始,指定时从length-1开始
    let arr = [
    {value: 1},
    {value: 2},
    {value: 3}
    ]
    arr.reduce((acc, cur) => { // 须指定初始值
    // 如果不指定,第一次循环acc={value:1}
    return acc + cur.value
    },0)
  • flatMap() 对于一维数组与map无异,对多维数组能结构1层
    1
    2
    3
    let arr = ['asd','asd']
    let arrmap = arr.map(item=>item.split('')) // [ [ 'a', 's', 'd' ], [ 'a', 's', 'd' ] ]
    let arrflatmap = arr.flatMap(item=>item.split('')) // [ 'a', 's', 'd', 'a', 's', 'd' ]
  • entries() 返回新的数组迭代对象(Array Iterator)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    let arr = [1,2,3]   // 索引/元素 键值对
    let arrIterator = arr.entries()
    console.log(arrIterator); // Object [Array Iterator] {}
    console.log(arrIterator.next()); // { value: [ 0, 1 ], done: false }
    console.log(arrIterator.next()); // { value: [ 1, 2 ], done: false }
    console.log(arrIterator.next()); // { value: [ 2, 3 ], done: false }
    console.log(arrIterator.next()); // { value: undefined, done: true }
    let arr = [
    {value: 1},
    {value: 2}
    ]
    let arrIterator = arr.entries()
    for(let i = 0; i < arr.length + 1; i++) { // length比arr多1
    let item = arrIterator.next() // {value: [0, {value: 1}], done: false}
    if (!item.done) {
    console.log(item)
    }
    }
  • values() 返回新的数组迭代对象(Array Iterator)
  • keys() 返回新的数组迭代对象(Array Iterator)
    1
    2
    3
    4
    5
    let arr = ["a", "b", "c"];
    let arrIterator = arr.values()
    console.log(arrIterator); // Object [Array Iterator] {}
    console.log(arrIterator.next()); // { value: 'a', done: false }
    console.log(arr.keys().next()); // { value: 0, done: false }

Object