1.基本用法
ES6容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構.
能夠從數組中提取值,按照位置的對應關係對變量賦值.
本質上,這種寫法屬於模式匹配,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值.node
var [a, b, c] = [1, 2, 3]; var [d, ...array] = [1, 2, 3]; console.log(a); console.log(b); console.log(c); console.log(d); console.log(array); // [2, 3] let [foo, [[bar], baz]] = [1, [[2], 3]]; console.log(foo); console.log(bar); console.log(baz); let [, , third] = [1, 2, 3]; console.log(third); // 3
2.若是結構不成功,變量的值就等於undefined.
另外一種狀況是不徹底解構,即等號左邊的模式只匹配等號右邊數組的一部分,
這種狀況下,解構依然能夠成功.
若是等號的右邊不是數組(或者嚴格的說,不是可遍歷的結構),那麼將會報錯.數組
let [bar1, foo1] = [1]; console.log(bar1); // 1 console.log(foo1); // undefined
3.默認值
解構賦值容許指定默認值
注意,ES6內部使用嚴格相等運算符(===)判斷一個位置是否有值,因此,若是一個數組成員
不嚴格等於undefined,默認值是不會生效的.函數
var [foo = true] = []; console.log(foo); // true var [x, y = 'b'] = ['a']; console.log(x); // 'a' console.log(y); // 'b' var [xx, yy = 'b'] = ['a', undefined]; console.log(xx); // 'a' console.log(yy); // 'b' // 若是一個數組成員是null,默認值就不會生效,由於null不嚴格等於undefined var [xxx = 1] = [undefined]; var [yyy = 1] = [null]; console.log(xxx); // 1 console.log(yyy); // null // 若是默認值是一個表達式,那麼這個表達式是惰性求值的,即只有在用到的時候纔會求值 // 由於x能取到值,因此函數f根本不會執行 function f() { console.log('aaa'); } let [xxxx = f()] = [1];
// 默認值能夠引用解構賦值的其餘變量,但該變量必須已經聲明 let [x = 1, y = x] = []; console.log(x); // 1 console.log(y); // 1 let [xx = 1, yy = xx] = [2]; console.log(xx); // 2 console.log(yy); // 2 let [xxx = 1, yyy = xxx] = [1, 2]; console.log(xxx); // 1 console.log(yyy); // 2 let [xxxx = yyyy, yyyy = 1] = []; // ReferenceError console.log(xxxx); // undefined console.log(yyyy); // 1
1.解構不只能夠用於數組,還能夠用於對象.
對象的解構與數組有一個重要的不一樣,數組的元素是按次序排列的,變量的取值由它的位置決定.
而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值.
也就是說,對象的解構賦值的內部機制,是先找到同名屬性,而後再賦給對應的變量.
真正被賦值的是後者,而不是前者.
這實際上說明,對象的解構賦值是如下形式的簡寫.code
var { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' }; var { foo, bar } = { foo: 'aaa', bar: 'bbb' }; console.log(foo); // 'aaa' console.log(bar); // 'bbb' // 若是變量名與屬性名不一致,必須寫成下面這樣 var { foo1: baz1 } = { foo1: 'aaa', bar: 'bbb' }; // console.log(foo1); // Uncaught ReferenceError: foo1 is not defined console.log(baz1); // 'aaa' let { first: f, last: l } = { first: 'hello', last: 'world' }; console.log(f); // 'hello' console.log(l); // 'world'
2.和數組同樣,解構也能夠用於嵌套解構的對象對象
// 注意,這時p是模式,不是變量,所以不會被賦值 var obj = { p: [ 'hello', { y: 'wrold' } ] }; var { p: [x, { y }] } = obj; console.log(x); // 'hello' console.log(y); // 'world' // 只有line是變量,loc和start都是模式,不會被賦值 var node = { loc: { start: { line: 1, column: 5 } } }; var { loc: { start: { line } } } = node; console.log(line); // 嵌套賦值 let obj1 = {}; let arr = []; ({ foo: obj1.prop, bar: arr[0] } = { foo: 123, bar: true }); console.log(obj1); // {prop:123}, obj1.prop被賦值123,因此obj1是一個對象 console.log(arr); // [true], arr[0]被賦值爲true,因此arr是一個數組