[譯]JavaScript ES6解構賦值指南

菜菜蔡偉發表於2015-06-19

前言

讓我們來仔細地看看ES6所帶來的更清晰的變數宣告與賦值語法。現今的變數宣告語法十分的直接:左邊是一個變數名,右邊可以是一個陣列:[]的表示式或一個物件:{}的表示式,等等。解構賦值允許我們將右邊的表示式看起來也像變數宣告一般,然後在左邊將值一一提取。聽起來有點迷糊?讓我們一起看看下面的例子就好。

陣列的解構賦值

現在假設我們有一個value變數,其值為[1, 2, 3, 4, 5]。然後我們想給陣列的前三個元素分別宣告一個變數。傳統的做法是單獨宣告和賦值每一個變數:

jsvar value = [1, 2, 3, 4, 5];
var el1 = value[0];
var el2 = value[1];
var el3 = value[0];

有了這幾個新變數,我們原本的value現在可以被表示為[el1, el2, el3, 4, 5],因為我們現在並不關心後兩個元素,所以也可以說被表示為[el1, el2, el3]。那麼現在,ES6允許我們在左邊使用這個表示式來達到和上一個程式碼塊一樣的效果:

jsvar value = [1, 2, 3, 4, 5];
var [el1, el2, el3] = value;

右邊不必一定是變數名:

jsvar [el1, el2, el3] = [1, 2, 3, 4, 5];

左邊也不必一定是宣告:

jsvar el1, el2, el3;
[el1, el2, el3] = [1, 2, 3, 4, 5];

這使我們通過僅僅使用兩個變數名,就可以交換兩個變數的值,這是從前的JavaScript不可能辦到的事情:

js[el1, el2] = [el2, el1];

解構賦值也是可巢狀的:

jsvar value = [1, 2, [3, 4, 5]];
var [el1, el2, [el3, el4]] = value;

ES6中,返回一個陣列的函式更像一個頭等公民了:

jsfunction tuple() {
  return [1, 2];
}

var [first, second] = tuple();

同樣可以通過簡單地在指定位置省略變數來忽略陣列中的某個元素:

jsvar value = [1, 2, 3, 4, 5];
var [el1, , el3, , el5] = value;

這使得從正規表示式裡取出匹配的分組的過程十分得簡潔:

jsvar [, firstName, lastName] = "John Doe".match(/^(w+) (w+)$/);

更進一步,預設值同樣也可以被指定:

jsvar [firstName = "John", lastName = "Doe"] = [];

需要注意的是預設值只會在對undefined值起作用,下面的例子中firstNamelastName都將是null

jsvar [firstName = "John", lastName = "Doe"] = [null, null];

rest引數(...變數名)讓事情變得更有趣,它使你可以得到陣列中“剩餘“的元素。下面這個例子中,tail變數將接收陣列中”剩餘“的元素,為[4, 5]:

jsvar value = [1, 2, 3, 4, 5];
var [el1, el2, el3, ...tail] = value;

不幸的是,ES6中rest引數的實現非常原始,rest引數之後不能再有其他引數(即只能是最後一個引數)。所以下面例子中的這些非常有用模式,在ES6中是不可能的(會報錯):

jsvar value = [1, 2, 3, 4, 5];
var [...rest, lastElement] = value;
var [firstElement, ...rest, lastElement] = value;

物件的解構賦值

現在,你已經對陣列的解構賦值有了清晰的認識,讓我們來看看物件的解構賦值。它們幾乎以同樣的方式工作,僅僅是從陣列變成了物件:

jsvar person = {firstName: "John", lastName: "Doe"};
var {firstName, lastName} = person;

ES6允許變數名與對應的屬性名不一致。下面的例子中,name變數將會被宣告為person.firstName的值:

jsvar person = {firstName: "John", lastName: "Doe"};
var {firstName: name, lastName} = person;

深層巢狀的物件也不會有問題:

jsvar person = {name: {firstName: "John", lastName: "Doe"}};
var {name: {firstName, lastName}} = person;

你還可以巢狀些陣列在裡面:

jsvar person = {dateOfBirth: [1, 1, 1980]};
var {dateOfBirth: [day, month, year]} = person;

或者一些其他的:

jsvar person = [{dateOfBirth: [1, 1, 1980]}];
var [{dateOfBirth}] = person;

和陣列解構賦值一樣,物件解構賦值也可以使用預設值:

jsvar {firstName = "John", lastName: userLastName = "Doe"} = {};

預設值同樣也只會在對undefined值起作用,下面的例子中firstNamelastName也都將是null

jsvar {firstName = "John", lastName = "Doe"} = {firstName: null, lastName: null};

函式引數的解構賦值

ES6中,函式的引數也支援解構賦值。這對於有複雜配置引數的函式十分有用。你可以結合使用陣列和物件的解構賦值。

jsfunction findUser(userId, options) {
  if (options.includeProfile) ...
  if (options.includeHistory) ...
}

通過ES6,這會看上去更清晰簡潔:

jsfunction findUser(userId, {includeProfile, includeHistory}) {
  if (includeProfile) ...
  if (includeHistory) ...
}

最後

ES6的解構賦值給JavaScript的語法帶來了更多的現代化。它在減少了程式碼量的同時,增加了程式碼的可讀性和表現力。

原文地址

https://strongloop.com/strongblog/getting-started-with-javascript-es6-...

相關文章