ES6解構賦值的簡單使用
相較於常規的賦值方式,解構賦值最主要的是'解構'兩個字,在賦值的過程中要清晰的知道等號右邊的結構.
先簡單地看一下原來的賦值方式.
1 |
var a=[1,2]
|
分析一下這句程式碼的幾個點:
(1)變數申明和賦值
var a; a=[1,2] //你可以理解這兩個操作是分開的,雖然是一句程式碼.宣告變數都會出現變數名的提升(也就是是宣告變數的這句程式碼會被提升到生效作用域的最前面),區別在於'var'宣告的是全域性變數,而'let const'宣告的是塊級作用域變數.
(2)結構對應
1 2 3 4 |
var a;
a=[1,2];
a=12; a={name: '小明' ,age:18}
|
解構賦值
結合上面的的例子,假如我現在只想要{name:'小明',age:18}這個物件中的'name'屬性,原來的做法
1 2 |
var a={name: '小明' ,age:18}
console.log(a.name)
|
就需要通過點語法去獲取,實際開發中,我們的資料很多時候是巢狀很多層的,所以就會出現類似'a.b.c.d'這類程式碼.看著讓人頭暈,而解構賦值就是解決這個問題的方案之一
基本用法
(1)宣告和賦值
陣列
1 |
let [a] = [1];
|
[變數名]:變數名可隨意
物件
1 |
let {name} = {name: '小明' ,age:18}
|
{變數名}:變數名必須是物件中的屬性名
(2)結構對應(重難點)
陣列(要位不要名)
物件(要名不要位)
完全解構
陣列:
a:按順序
1 2 3 |
let [a, b, c] = [1, 2, 3];
console.log(a,b,c)
//1,2,3
|
1 |
這樣賦值的語義是我知道右邊是一個有三個元素的數字,所以我聲明瞭一個數組,三個元素分別是a,b,c和右邊的三個元素對應.所以a=1,b=2,c=3
|
b:打亂順序
1 2 3 |
let [a, c, b] = [1, 2, 3];
console.log(a,b,c)
//1,3,2
|
1 |
因為三個變數的位置變了,所以其對應的元素(值)也就變數
|
物件:
a:按順序
1 2 3 |
let {name,age} ={name: '小明' ,age:18}
console.log(name,age)
//小明,18
|
b:打亂順序
1 2 3 |
let {age,name} ={name: '小明' ,age:18}
console.log(name,age)
//小明,18
|
雖然變數的宣告前後順序變了,但是物件中的值沒變,它最終還是根據屬性名去找值,所以結果沒變
c:不存在的屬性名
1 2 3 |
let {name,sex} ={name: '小明' ,age:18}
console.log(name,sex)
//小明,undefined
|
巢狀解構
陣列:
let [a, [b,c], d] = [1, [2, 3], 4]; console.log(a,b,c,d) //1,2,3,4 //反正結構和位置一一對應就行了.
物件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const obj={
man:{
student:{
name: '小明' ,
age:18
}
}
}
let {man:{student}} = obj //obj裡面有個man,然後裡面有個student,注意這一行程式碼裡變數就只有一個student,並沒有man
console.log(man,student) // undefined,{name:'小明',age:18}
let {man:{student:{name}}} = obj //同理,逐層拿到最後的name值,而且也只有name這一個屬性
console.log(name) //小明
//如何同時拿到巢狀的每層的資料
let {man,man:{studengt},man:{student:{name}}} = obj
console.log(man,student,name) //{student:{name:'小明',age:18}},{name:'小明',age:18},18
|
不完全解構
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
let [a, b] = [1, 2, 3];
console.log(a,b,c)
//1,2
//這裡變數只有兩個,但是陣列中元素有三個.這裡還是根據位置對應原理就行.a表示陣列中的第一個元素,b表示第2個.而第三個元素我不要.
let [a, [b], d] = [1, [2, 3], 4];
console.log(a,b,d)
//1,2,4
//巢狀解構同樣也可以不完全解構,根據實際需要,需要哪個就解構賦值哪個
let [, , c] = [1, 2, 3];
console.log(c)
//3
//注意這裡是完全解構,只不過前兩個元素我雖然解構了,但是我不要.因為位置對應的關係,所以必須有兩個佔位的,才能拿到第三個.
//放在這裡是為了方便理解為啥前面兩個明明不要還得寫兩個','
|
超量賦值(自己瞎編的詞)
1 2 3 4 5 6 |
let [a,b,c,d] = [1,2,3]
onsole.log(a,b,c,d)
//1,2,3,undefined
//因為前三個元素都能對應找到,而第四個找不到,但是已經聲明瞭,沒有值.
//物件同理,如果出現了物件中沒有的屬性就會得到undefined
|
(3)重新命名(先取再重新命名)
陣列:我們上面說過,陣列解構的時候只要注意位置對應就行了,名稱啥的無所謂,你喜歡叫什麼變數名就什麼變數名
物件:物件解構的時候是要屬性名對應才能取到值.但是沒有說取到值之後不能重新命名啊.一定要取到值之後在命名
1 2 3 4 5 |
let {name:myName,age} ={name: '小明' ,age:18}
//這裡name:myName的意思是:取到name屬性值,冒號後面的變數名沒有花括號,意思是把我取到的值交給冒號後面的變數名,即'myName'.相當於把name變數重新命名為myName
//而student:{name},同樣是'屬性名:'意思一樣,取裡面對應的屬性,冒號後面還有花括號,所以再解構,取student裡面的name屬性
console.log(name,myName,age)
//undefined,小明,18
|
(4)預設值(先取再預設)
陣列
1 2 3 4 |
let [a=0, b=0,c=10] = [1, 2];
console.log(a,b,c) //1,2,10
//這裡a,b,c在左邊都先給了個預設值,但是這裡是超量解構,a和b都成功取到值,但是c沒取到,所以最終是預設值10,如果沒有預設值就是undefined
|
物件
1 2 3 4 5 6 |
let {name:sex= '男' } ={name: '小明' ,age:18}
console.log(sex) //小明
let {name:{sex= '男' }} = {name: '小明' ,age:18}
console.log(sex) //男
//這裡剛好通過這兩個例子區分一下重新命名和巢狀
|
(5)字串解構
字串的解構可以理解為一維陣列的解構,這在處理字串的時候特別方便.
1 2 |
let [a,b,c] = '123'
console.log(a,b,c, typeof c) //1,2,3,string 解構出來的是字元型別的資料
|
長度
1 2 3 4 5 6 |
let {length:s} = '123'
console.log(s, typeof s) //3,number
//同理,陣列也有長度
let {length:s} = [1,2,3]
console,log(s, typeof s) //3,number
|
(6)函式引數自動解構
1 2 3 4 5 |
function look([x,y]){
console.log(x,y)
}
look([1,2]) //1,2
|
引數預設值陷阱單獨再寫一篇
(7)先宣告再賦值(少用)
陣列
1 2 3 4 |
let a;
let b;
[a,b]=[1,2]
console.log(a,b) //1,2
|
物件
1 2 3 |
let x;
{x}={x:1,y:1} //報錯 主要還是大括號的原因,js在行首遇到{}會把它當做程式碼塊執行,所以會報錯.
({x}={x:1,y:1}) //這樣可以解決問題,但是儘量別引入(),問題會變得複雜
|
到這裡為止,解構賦值的日常使用沒問題了,它帶來了不少方便,但也會產生一些新bug,比如:let {data} =res 的寫法,假如res裡面並沒有data屬性,那就會undefined,所以還是得明確等號右邊的解構.
原文地址:https://www.cnblogs.com/shyno/p/12156854.html