# 数组的扩展

# 扩展运算符

  • 将一个数组转为用逗号分隔的参数序列
const a1 = {...[1, 2, 3]};
  console.log(a1);
  // {
  //   "0": 1,
  //   "1": 2,
  //   "2": 3
  // }

  function add(a, b) {
    console.log(a + b);
  }

  add(...[1, 2]) // 3

  function push(arr, items) {
    arr.push(...items)
    console.log(arr);
  }
  push([], [1,2,3,4,5])
  // [
  //   1,
  //   2,
  //   3,
  //   4,
  //   5
  // ]
  push([{
    a:1
  }], [{
    b: 1
  }, {
    c: 1
  }])
  // [
  //   {
  //       "a": 1
  //   },
  //   {
  //       "b": 1
  //   },
  //   {
  //       "c": 1
  //   }
  // ]
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
44
  • 如果扩展运算符后面是一个空数组,则不产生任何效果
[...[], 1] // [1]
1
  • 只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错
(...[1, 2]) // error
console.log(...[1, 2]) // 1 2
1
2
  • 替代函数的 apply 方法
function fn(a, b, c) {
  console.log(arguments);
}

const params = [1, 2, 3];
// apply 传递多个参数
fn.apply(this, params)

// 扩展运算符替代apply
fn(...params)

let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
// Array.prototype.push.apply(arr1, arr2)
arr1.push(...arr2)
console.log(arr1); // [1, 2, 3, 4, 5, 6]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 扩展运算符的应用

  • 复制数组
// es5 使用 concat() 
// a4 = a3.concat()
let a3 = [1, 2, 3]
let a4 = [...a3]
a4[0] = 0
console.log(a3, a4); // [1,2,3]  [0,2,3]
1
2
3
4
5
6
  • 合并数组

浅拷贝

// 合并数组
const a5 = [...a3, ...a4]
console.log(a5); // [1, 2, 3, 0, 2, 3]
1
2
3

# Array.from()

  • 将类似数组的对象(必须有 length 属性)和可遍历的对象(包括Set Map)转换为真正的数组
// 将类似数组的对象 转为数组 索引必须是正确的
const likeArr = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
}

const likeA1 = Array.from(likeArr)
console.log(likeA1); // ['a', 'b', 'c']

// 类似数组的对象 有length属性
const likeA2 = Array.from({
  length: 3
})
console.log(likeA2); // [undefined, undefined, undefined]

// nodelist
const ps = document.querySelectorAll('p')
console.log(Array.from(ps)); // [p, p, p]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  • polyfill
const toArray = (() =>
  Array.from ? Array.from : obj => [].slice.call(obj)
)();
1
2
3
  • 第二个参数,类似数组的 map 方法
const likeArr = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
}
const second = Array.from(likeArr, a => a + 'A')
console.log(second); // ['aA', 'bA', 'cA']
1
2
3
4
5
6
7
8

# Array.of()

  • 用于将一组值转换为数组
Array.of(1,2,3,4) // [1,2,3,4]
1
  • 弥补数组的构造函数 Array() 的不足
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
1
2
3
  • Array.of() 可以替代 Array() 或 new Array() ,行为统一 不存在由于参数不同导致的重载
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]
1
2
3
4

# 数组的空位

  • 数组的某一位置没有任何值
Array(3) // [ , , ,]
1
  • 空位不是 undefined ,一个位置的值等于 undefined 依然是有值的,空位是没有任何值的
const un = [undefined, undefined];
0 in un // true
const empty = [,,]
0 in empty // false

un.length // 2
empty.length // 2

Object.keys(un) // ['0', '1']
Object.keys(empty) // []
1
2
3
4
5
6
7
8
9
10
  • ES5 对空位的处理
  1. forEach() filter() reduce() every() some() 会跳过空位
  2. map() 会跳过空位,但会保留这个值
  3. join() toString() 会将空位视为 undefined ,而 undefined 会被处理成空字符串
// forEach方法
[,'a'].forEach((x,i) => console.log(i)); // 1

// filter方法
['a',,'b'].filter(x => true) // ['a','b']

// every方法
[,'a'].every(x => x==='a') // true

// reduce方法
[1,,2].reduce((x,y) => x+y) // 3

// some方法
[,'a'].some(x => x !== 'a') // false

// map方法
[,'a'].map(x => 1) // [,1]

// join方法
[,'a',undefined,null].join('#') // "#a##"

// toString方法
[,'a',undefined,null].toString() // ",a,,"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • ES6 对空位的处理,将空位转为 undefined
Array.from(['a',,'b'])
// [ "a", undefined, "b" ]

[...['a',,'b']]
// [ "a", undefined, "b" ]

[,'a','b',,].copyWithin(2,0) // [,"a",,"a"]

new Array(3).fill('a') // ["a","a","a"]

let arr = [, ,];
for (let i of arr) {
  console.log(1);
}
// 1
// 1

// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]

// keys()
[...[,'a'].keys()] // [0,1]

// values()
[...[,'a'].values()] // [undefined,"a"]

// find()
[,'a'].find(x => true) // undefined

// findIndex()
[,'a'].findIndex(x => true) // 0
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