最近看了一个vue的项目,发现作者大量使用了ES6的语法,包括async, Promise, Set, Map还有一些解构赋值, 才发现自己对于ES6的语法缺乏了总结和运用,看得有点艰难,所以重新学习了阮一峰老师的教程并用自己的理解做了一些笔记:
1. 数组解构赋值
(1)按照变量位置对应赋值 ---- "匹配模式"
1 let [a, b, c] = [1, 2, 3] 2 console.log(a, b, c) // 1 2 3 3 let [foo, [[bar], baz]] = [1, [[2], 3]] 4 console.log(foo, bar, baz) // 1 2 3
5 let [a, , c] = [1, 2, 3]
6 console.log(a, c) // 1 3
7 let [x, y, z] = [1, [2, 3], 4]
8 console.log(x, y, z) // 1 [2,3] 4
(2) 有时候如果遇到解构不成功时,就会返回undefined
let [a, b, c] = [1] console.log(a, b, c) // 1 undefined undefined
(3)解构成功但不完全解构 :
1,2分别赋值给了a,c 但是没有任何变量可以被3赋值
同理:2赋给了y, 但是3没有赋给任何变量
let [a, c] = [1, 2, 3] console.log(a, c) // 1 2 let [x, [y], z] = [1, [2, 3], 4] console.log(x, y, z) // 1 2 4
(4)数据类型不一样时报错 : 因为左边定义了一个数组,数组内元素为a变量 , 但是右边没有相同的数据结构, 故报出"Uncaught TypeError: Invalid attempt to destructure non-iterable instance" 错误 ,这部分涉及到Interator接口的问题,后边章节会提到。
1 let [a] = 1; 2 let [a] = false; 3 let [a] = NaN; 4 let [a] = undefined; 5 let [a] = null; 6 let [a] = {};
7 console.log(a) // 报错: Uncaught TypeError: Invalid attempt to destructure non-iterable instance
(5)结构Set数据结构, Set本身是ES6新增的一种类似数组的数据结构 , 但它内部元素没有重复值,也经常被用到数组去重的操作。
let [a, b, c] = new Set([1, 2, 3]) console.log(a, b, c) // 1 2 3
let a = new Set([1,2,3])
console.log(...a) // 1 2 3
console.log(a) // Set({})
(6)默认值: 有默认值的变量, 如没赋值则取默认值, 未赋值也无默认值则返回undefined
1 let [a = 1] = [] 2 console.log(a) // 1 3 let [b] = [] 4 console.log(b) // undefined 5 let [c = 1] = [undefined] 6 console.log(c) // 1
2. 对象解构赋值
对象解构赋值和数组解构赋值类似, 只是将[]换成{}, 赋值由值换成键值对
(1)简单的对象解构赋值 : 注意 --- 返回的是值而非键值对
1 let {a, b} = {a: 'AAA', b: 'BBB'} 2 console.log(a, b) // AAA BBB
1 let {a, c} = {a: 'AAA', b: 'BBB'} 2 console.log(a, c) // AAA undefined
1 let {a, b} = {a: 'AAA', b: 'BBB'} 2 console.log(a, d) // Error: d is not defined
以上三种情况对比可以看出 :
a , b必须对应右边的键key,才有返回值value
c 在右边没有被赋值, 所有返回了undefined
而 d 没有被声明, 自然会报错 Error: d is not defined
其实对象的解构赋值完整格式如下 : 但是在ES6中推荐声明键和值一样时只需写键即可, 在Vue,React项目中已经大量使用简写方式,在eslint语法检测中, 如键值都写也会被报出警告。
1 let {a: a, b: b} = {a: 'AAA', b: 'BBB'} 2 console.log(a, b) // AAA BBB
如键值不同,才必须使用完整格式
let {a: c, b: d} = {a: 'AAA', b: 'BBB'} console.log(c, d) // AAA BBB
(2)默认值和解构不成功,以及不完全解构, 与数组的形式类同, 不再赘述。
3.字符串解构赋值
字符串结构赋值其实是把字符串中每个字符赋值到给定的变量
1 let [a, b, c, d, e, f] = 'hello' 2 console.log(a, b, c, d, e, f) // h e l l o undefined
其中f 声明了但未被赋值,所以返回 undefined
4. 数值和布尔值的解构赋值不常用,此处省略
5. 函数参数的解构赋值
1 function sum1(a, b) { 2 return a + b 3 } 4 5 console.log(sum1(3, 4)) 6 7 function sum2([a, b]) { 8 return a + b 9 } 10 11 console.log(sum2([3, 4]))
以上两个函数结果是一样的,第一种是常规的声明了形参a,b, 第二种是以数组解构赋值的方式把值传给了数组内的两个变量 a, b
(1)无默认值与有默认值 : 当声明未赋值时有默认值返回默认值, 无默认值返回undefined
1 function foo({x, y} = {}) { 2 // console.log(x + y) // 3 3 return [x, y] 4 } 5 6 console.log(foo({x: 1, y: 2})) // [1, 2] 7 console.log(foo({x: 3})) // [3, undefined] 8 console.log(foo({})) // [undefined, undefined] 9 console.log(foo()) // [undefined, undefined]
1 function foo({x = 1, y = 1} = {}) { 2 // console.log(x + y) // 3 3 return [x, y] 4 } 5 6 console.log(foo({x: 1, y: 2})) // [1, 2] 7 console.log(foo({x: 3})) // [3, 1] 8 console.log(foo({})) // [1, 1] 9 console.log(foo()) // [1, 1]
6. 解构赋值一般用在哪些场景?
(1)变量交互
1 ## 传统的变量交换 2 var a = 1 3 var b = 2 4 console.log(a) // 1 5 console.log(b) // 2 6 var x = a 7 a = b 8 b = x 9 console.log(x) // 1 10 console.log(a) // 2 11 console.log(b) // 1