咱们先来看一看MDN的官方定义javascript
展开语法(Spread syntax), 能够在函数调用/数组构造
时, 将 数组表达式或者 string在语法层面展开;
还能够在构造字面量对象
时, 将 对象表达式按key-value的方式展开。(译者注: 字面量通常指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造方式)
从定义咱们能够了解到展开语法的使用场景以下java
函数
调用数组
构造字面量对象
(ES2018)做用以下api
数组
字符串
对象
(只能用于构造字面量对象)// 展开数组 console.log(...[1,2,3]) // 1 2 3 // 展开字符串 console.log(...'hello world') // h e l l o w o r l d // 展开对象【没法使用,会报错】 console.log(...{a:1}) // Uncaught TypeError
在函数调用时使用展开语法时,须要特别注意数组、字符串实际上是被展开成了参数序列。
还记得rest参数
是将参数都都收集为数组吗?展开语法
正好是它的逆运算——将数组展开为参数
还有注意的是rest参数在函数定义时使用【处理形参】,展开语法在函数调用时使用【处理实参】
,可能有些拗口,下面看个例子你们就明白了数组
function test(x, y, ...params) { // 定义一个函数时,使用的是rest参数 console.log(...params) // 调用一个函数时,使用的是rest参数 }
let numArr = [1, 10, 2, 234] Math.max.apply(null, numArr) // 彻底等价于 Math.max(...numArr) // 将numArr展开为参数序列
由于new的时候是没法调用apply的,因此展开语法这个时候起到了很牛X的做用浏览器
function Person(name, age, weight) { this.name = name this.age = age this.weight = weight } let blues = new Person('blueswong', '16', '60') // 彻底等价于 let blues = new Person(...['blueswong', '16', '60'])
这在须要生产不少个实例时,很是有用app
function Person(name, age, weight) { this.name = name this.age = age this.weight = weight } let persons = [['blues1', '16', '60'], ['blues2', '16', '60'], ['blues3', '16', '60']] let createdPersons = {} persons.forEach(e => { console.log(e[0]) createdPersons[e[0]] = new Person(...e) })
// 展开数组 let arr1 = [1, 2, 3] let arr2 = [0, ...arr1, 4] // [0, 1, 2, 3, 4] // 展开字符串 let arr1 = [1, 2, 3, ...'456'] // [1, 2, 3, "4", "5", "6"]
以往咱们将已有数组的 元素插入到新数组的中,须要借用一些API例如push/unshift/splice/concat
,如今咱们使用展开语法能够对上述api进行替换。须要特别强调的是,这在建立新数组的时候才比较方便函数
let arr = [4, 5] let arr2 = [6, 7, 8] // 在数组任意位置增长元素 let newArr1 = [1, 2, 3, ...arr] // [1, 2, 3, 4, 5] let newArr2 = [...arr, 1, 2, 3] // [4, 5, 1, 2, 3] let newArr3 = [1, ...arr, 2, 3] // [1, 4, 5, 2, 3] let newArr4 = [1, 2, ...arr, 3] // [1, 2, 4, 5, 3] // 链接两个数组 let newArr5 = [...arr, ...arr2] // [4, 5, 6, 7, 8]
若是是对原有的数组进行操做,原有API
+在函数调用中使用展开语法
比较方便this
let obj = {a: 1} let arr = [2, 1, '的', obj] // 在数组任意位置增长元素 let newarr = [...arr] // [2, 1, '的', {a: 1}] // 但仅仅是浅拷贝,新数组中的{a:1}与obj仍是指向了相同的内存 newarr[3].a = 2 console.log(obj) // {a: 2}
常见的实现对象浅拷贝的方法
let obj = {a: '10', b: {c: 10}, d: [1, 2, 3]} // 1. 遍历 let newObj = {} for (let key in obj) { newObj[key] = obj[key] } console.log(newObj) // 2.使用assign let newObj1 = Object.assign({}, obj) console.log(newObj1)
使用展开语法实现
let newObj2 = {...obj}
因为这是ES2018的语法,如今浏览器支持的并不到位,所以笔者就不作过多介绍了。你们能够 去mdn上查看