最近看了一個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
