扩展运算符「spread」的交谈

原文链接 - 航洋无声 - Github

扩展运算符,看起来和 rest 参数 外观相似,也是三个点「...」,
不过和 rest 参数功能可是不一样呢

扩展运算符号,分二种情况

  1. iterable「一般情况为数组」
  2. enumerable「一般情况为对象」

在标准的 ES2015 中,只有针对 iterable 数据实现了扩展运算符
它把 iterable 数据的数据序列转换为用 逗号分割的参数序列

比如:

let array = [5, 12]
let arrayCopy = [11, ...array]
// 此行代码类似于:let arrayCopy = [11, 5, 12]
// arrayCopy ==> [11, 5, 12]

console.log(...[5, 12])
console.log(5, 12)
// 上面 2 行代码意义一样
// 输出结果都是是:5 12

经过上面的 2 个列子,
应该能更好的理解「扩展运算符的结果是 逗号分隔的参数序列」的含义

不过有个需要注意的点:
非 iterable 数据执行扩展运算符,会报错

在 ES7 的 某个提案 中,
讲扩展运算符引入 enumerable 数据

比如:

let obj = {name: 'hangyangws'}
let objCopy = {...obj}
console.log(objCopy) // 输出:{name: 'hangyangws'}

其实 enumerable 数据的扩展运算符底层实现是利用了 Object.assign

Object.assign(target, ...sources) 我们比较熟悉,有 2 个特点:

  1. sources 参数如果是「原始类型」会被包装为「对象」
  2. sources 参数如果是 null 和 undefined 会被忽略

比如:

Object.assign({}, null) // 结果为:{}
Object.assign({}, undefined) // 结果为:{}

Object.assign({}, 0) // 结果为:{}
Object.assign({}, 'FJ') // 结果为:{0: "F", 1: "J"}
// 所以有个点可以注意一下:
// 只有字符串的包装对象才可能有自身可枚举属性
// 对于「数字」,结果和 null、undefined 类似

既然扩展运算符有 2 种情况,那么 JS 解释器怎么知道使用哪一种?
所以扩展运算符会根据代码的具体的 执行上下文 判断

比如:

let test = [...null]
// 报错:null is not iterable

let test = {...null}
// test ===> {}

你可能感兴趣的:(扩展运算符「spread」的交谈)