ES6解構賦值原理詳解

ES6解構賦值

ES6變量的解構賦值本質上是「模式匹配」,只要等號兩邊的模式相同,左邊的變量就會被賦予匹配的右邊的值,若是匹配不成功變量的值就等於undefined數組

數組的解構賦值

ES6中只要某種數據有Iterator接口(也就是能夠循環迭代),均可以進行數組的解構賦值。
Example1:數組的解構瀏覽器

var [a,b,c] = [1,2,3];
var [d,[e],...f] = [4,[5],6,7,8];
console.log(a); //結果爲1,b,c結果是2,3
console.log(e,f) //e結果爲5,f的結果是一個數組:[6,7,8]

Example2:Set解構賦值babel

let [x,y] = new Set([1,2]);
console.log(x,y);   //結果爲1和2

Example3:Generator函數解構賦值函數

function* fun(){
    let a = 0;
    let b = 1;
    while(true){
        yield a;
        [a,b] = [b,a+b];
    }
}
let [first,second,third,fourth,fifth,sixth] = fun();
console.log(sixth); //結果爲5

Example4:默認值code

var [a=3,b=5] = [undefined,4];
console.log(a,b); //結果爲3和4

代碼解讀:上面的代碼等同於以下:
Example4:對象

var a;
var b;
var c = [undefined,4];  //這步驟是另加上去做爲數組引用的
if(c[0] !== undefined){
    a = c[0];
}else{
    a = 3;
}
if(c[1] !== undefined){
    b = c[1];
}else{
    b = 5;
}
console.log(a,b);   //結果爲3,4

對象的解構賦值

數組的解構是按次序排列的,變量取值由位置決定的,而對象的屬性是沒有順序的,變量必須與屬性同名才能取到正確的值。接口

Exampleip

var {b,a} = {a:3,b:4}
console.log(a,b);   //結果爲3,4

代碼解讀:上面的代碼等同下面的代碼
Example開發

var _ab = {a:3,b:4};
var b = _ab.b;
var a = _ab.a;
console.log(a,b);   //結果爲3,4

注意:對象的解構至關於先定義了後一個對象變量爲_ab,再對前一個對象解構出來的變量按照對象前後順序分別進行申明並使用對象_ab去按照該變量名賦值相應的值。若是前一個對象中的變量和後一個對象中的屬性不一致,直接定義是確定賦值失敗的,解決方法以下:
Example字符串

var {b:c,a:d} = {a:3,b:4};
console.log(b,c,a,d)    // 分別是undefined,4,undefined,3

代碼解讀:上面代碼等同下面的代碼

Example

var _ab = {a:3,b:4};
var c = _ab.b;
var d = _ab.a;
console.log(b,c,a,d)    // 分別是undefined,4,undefined,3

注意:例子能夠看出對象的解構的內部機制是先找到同名屬性,而後再賦予相應的變量,真正被賦予的是前一個對象後一個變量,即c,d;而不是前一個對象前一個模式,即b,a;

發現:若是想要上一個例子的模式不爲undefined,那麼代碼能夠寫成以下:

var e = {b:c,a:d} = {a:3,b:4};
console.log(e.b,b,c,e.a,a,d)    // 分別是4,undefined,4,3,undefined,3

注意:以上代碼在使用babel轉換的時候可能會出錯,只在瀏覽器中有用,因此最好不要代碼中使用,只理解就好

對象解構賦值與數組解構賦值在申明的時候的一點區別:

Example1:數組

let a;
[a] = [3]
console.log(a); //結果爲3

Example2:對象

let a;
{a} = {a:3}
console.log(a); // 報錯:SyntaxError

代碼解讀:JavaScript引擎會將[a]理解成一個數組,而將{a}理解成什麼呢?對於{a}這個代碼在JS中可能會存在兩種解釋,一種是它是一個表達式,表示含有a屬性的一個對象;第二種它是一個語句(代碼塊),爲了消除這種歧義,js開發人員規定只要行首是大括號的,一概解析成代碼塊。解決上訴問題的代碼以下:
Example3:對象

let a;
({a} = {a:3})   //JS中括號中的都是表達式
console.log(a); // 結果3

解構賦值中的圓括號問題

Example

let [(a)] = [1];
let {(b):c} = {b:2};
let {d:(e)} = {d:2};    //都報錯:SyntaxError

注意:以上出現錯誤的緣由都是:一、它們都是申明語句;二、圓括號中的都屬於模式中的一部分。要同時不知足以上兩個條件是比較困難的,因此,ES6規定,只要可能致使解構歧義就不得使用圓括號。因此,建議在寫的過程當中除了上面的那個對象圓括號的例子可使用外,其餘的狀況都不能使用。

ES6中還存在字符串、數組、布爾值等各類解構賦值,基本概念和原理都和對象的解構賦值相似,這裏就不在所有列舉了。

相關文章
相關標籤/搜索