ES的解構賦值-數組&對象

什麼是解構?

按照必定的模式從數組或者對象中取值,對變量進行賦值的過程稱爲「解構」數組

在 ES5 中,爲變量賦值只能直接指定值:spa

var a=1,b=2,c=3
a; // 1
b; // 2
c; // 3

可是在 ES6 中,咱們能夠被容許寫成:code

var [a,b,c]=[1,2,3];
a; // 1
b; // 2
c; // 3

ES6 中能夠很明顯看出來,咱們能夠在數組中取數據,按照位置的對應關係對變量賦值。對象

[默認值]

解構賦值容許使用默認值
var [foo = true] = [];
foo; // true
[x,y = 'b'] = ['a']
x; // "a"
y; // "b"
[x,y = 'b'] = ['a','c']
x; // "a"
y; // "c"

ES6 內部使用的是嚴格相等運算符(===)判斷一個位置是否有值。因此,若是一個數組成員不嚴格等於 undefind,默認值是不會生效的。rem

var [x = 1] = [undefined];
x; // 1
null == undefined // true
var [x = 1] = [null];
x; // null

上述代碼中,一個數組成員是 null,所以默認值不生效。由於 null 不嚴格等於 undefined。it

function f(){
    console,log('aaa');
}
let [x = f()] = [1]; // undefined ,不執行 f()
x; // 1

對象的解構賦值

var {foo,bar}={foo:"aaa",bar:"bbb"};
foo; // "aaa"
bar; // "bbb"

對象的解構賦值和數組有一個不一樣,數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。io

var {laf} = {foo:"aaa",bar:"bbb"};
laf; // undefined;

在上面代碼中,變量沒有對應的同名屬性,致使取不到值,最後等於 undefind。
實際上,對象的解構賦值是如下形式的簡寫。console

var { foo: foo, bar: bar } = { foo:"aaa", bar:"bbb" }

實際上,在對象的解構賦值的內部機制,是先找到同名屬性,而後在賦值給對應的變量。真正被賦值的是後者,而不是前者。function

var { foo : bar } = {foo : "aaaa"};
foo; // foo is not defined
bar; // "aaaa"

採用這種寫法是,變量的聲明和賦值都是一體的。對於 let 和 const 而言,變量不能從新聲明,因此一旦賦值的變量之前聲明過,就會報錯。class

let foo;
let {foo}={foo:'1'}
// Uncaught SyntaxError: Identifier 'foo' has already been declared

因此不能重複 let 聲明:

let foo;
({foo} = {foo:1})

對象的解構也能夠制定默認值。

var {x,y = 5} = {x:1};
x; // 1
y; // 5

默認值生效條件是,對象屬性嚴格不等於 undefined

var {x = 3} = {x: undefined};
x; // 3
var {x = 3} = {x:null};
x; // null

和數組同樣,解構也能夠用於嵌套解構的對象。

var obj={
    p:[
        "hello",
        {y:"world"}
    ]
}

這時的 p 是模式,不是變量,所以不會被賦值。若是 p 也要做爲變量賦值,應該寫成這樣:

var obj = {
    p:{
        "Hello",
        {
            y:"World"
        }
    }
}
let {p, p : { x , [ { y } ] = obj;

x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]

下面一個例子:

var {loc,loc:{start},loc:{ start: { { line,column } } }={
    loc:{
        start:{
            line:1,
            column:5
        }
    }
}
上面代碼有三次解構賦值,分別是對loc、start、line三個屬性的解構賦值。注意,最後一次對line屬性的解構賦值之中,只有line是變量,loc和start都是模式,不是變量。

賦值圖示

var obj = [];
var arr = [];

({foo:obj.prop,bar: arr[0]} = {foo:123,bar:true});

obj; // {prop:123}
arr; // [true]

若是解構模式是嵌套的對象,並且子對象所在的父屬性不存在,則會報錯

var {foo : {bar}} = {baz:'baz'};

正確的寫法:

var {foo,foo:{bar}}={foo:{bar:'bar'}};
相關文章
相關標籤/搜索