ES6學習-解構賦值

ES6容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構。解構賦值能夠用var、let、const聲明。且凡是具備Iterator接口的對象均可以進行解構賦值。而且解構的同時能夠爲其指定默認值。javascript

1.數組的解構賦值java

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

// ES6
let [a, b, c] = [1, 2, 3];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

let [a, [b, c]] = [1, [2, 3]];
console.log(a); //1
console.log(b); //2
console.log(c); //3

本質上,這種寫法屬於「模式匹配」,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。es6

let [a, b] = ['a'];
console.log(b) // undefined

若是解構失敗的話,對應的變量的值就是undefined。json

let [a, b, c] = [1, 2, 3, d];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

若是左面的變量只匹配到了右面的部分,則解構不徹底。數組

let [a, b = 2] = [1];
console.log(a); // 1
console.log(b); // 2

let [a = 1, b = a] = [];
console.log(a); // 1
console.log(b); // 1

let [a = b, b = 2] = [];
console.log(a); //  b is not defined

咱們能夠在解構的同時爲變量設置默認值。而且變量能夠引用其餘的解構變量,但這時,變量必須提早聲明。函數

2.對象的解構賦值ui

var { foo, bar } = { foo: 1, bar: 2 };
foo // 1
bar // 2

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

let { bar, foo } = { foo: 1, bar: 2 };
foo // 1
bar // 2

let { foo: a, bar:  b} = { foo: 1, bar: 2};
a // 1
b // 2

let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

對象的解構賦值的內部機制,是先找到同名屬性,而後再賦給對應的變量。真正被賦值的是後者。對象

let foo;
let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"

let baz;
let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz"

注意,採用這種寫法時,變量的聲明和賦值是一體的。對於letconst來講,變量不能從新聲明,因此一旦賦值的變量之前聲明過,就會報錯。上面代碼中,解構賦值的變量都會從新聲明,因此報錯了。不過,由於var命令容許從新聲明,因此這個錯誤只會在使用letconst命令時出現。若是沒有第二個let命令,上面的代碼就不會報錯。接口

let {x = 3} = {};
x // 3

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

let {x:y = 3} = {};
y // 3

let {x:y = 3} = {x: 5};
y // 5

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

let {x = 3} = {x: undefined};
x // 3

let {x = 3} = {x: null};
x // null

上面代碼中,若是x屬性等於null,就不嚴格相等於undefined,致使默認值不會生效。若是解構失敗,變量的值等於undefined

// 報錯
var {foo: {bar}} = {baz: 'baz'};

上面代碼中,等號左邊對象的foo屬性,對應一個子對象。該子對象的bar屬性,解構時會報錯。foo這時等於undefined,再取子屬性就會報錯。

3.字符串的解構

let [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

let {length : length} = 'hello';
length // 5

此時,字符串被轉換成了一個相似數組的對象。相似數組的對象都有一個length屬性,所以還能夠對這個屬性解構賦值。

4.函數參數的解構賦值

function add([x, y]){
  return x + y;
}
add([1, 2]);

5.使用場景

變量的解構賦值用途不少。

  a . 交換變量的值

[x, y] = [y, x];

  b . 函數返回多個值

// 返回一個數組
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一個對象
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

 c . 函數參數

// 參數有序
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 參數無序
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

 d . 提取JSON

let json = {
  a: 1,
  b: 2,
  c: 3
};
let { a, b, c } = json;

上面代碼能夠快速提取JSON數據的值。

 e . 遍歷Map結構

var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

若是隻想獲取鍵名,或者只想獲取鍵值。

// 獲取鍵名
for (let [key] of map) {
  // ...
}

// 獲取鍵值
for (let [,value] of map) {
  // ...
}

 f . 輸入模塊的指定方法

const { SourceMapConsumer, SourceNode } = require("source-map");

 

參考自 : http://es6.ruanyifeng.com/#docs/destructuring 

相關文章
相關標籤/搜索