回顧之前寫的代碼,處處能看到解構賦值。 讀取對象屬性和訪問數組內容是常常的操做。解構賦值可讓這種操做變得簡潔明瞭。 這篇文章中我介紹了 5 種解構方式,它們超出了基本的使用範疇。javascript
一般狀況下,交換變量的場景以下:java
let a = 1;
let b = 2;
let temp;
temp = a;
a = b;
b = temp;
a; // => 2
b; // => 1
複製代碼
temp
做爲臨時變量保存了 a
的值。而後 a
保存了 b
的值,b
保存了 temp
的值。react
解構的方式就比較簡單了,它沒有用到任何臨時變量,以下:redux
let a = 1;
let b = 2;
[a, b] = [b, a];
a; // => 2
b; // => 1
複製代碼
[a, b] = [b, a]
是一種解構賦值。右側的數組建立了 [b, a]
對應值是 [2, 1]
。第一個項 2 賦值給了 a,第二個項 1 賦值給了 b。數組
參數的個數是不受限定的,請參考下面的列子:ui
let zero = 2;
let one = 1;
let two = 0;
[zero, one, two] = [two, one, zero];
zero; // => 0
one; // => 1
two; // => 2
複製代碼
若是存在一個可能有空項的數組。你須要訪問其中任意位置的元素,可是這個元素不必定存在。 一般使用數組的長度屬性來遍歷:this
const colors = [];
let firstColor = 'white';
if (colors.length > 0) {
firstColor = colors[0];
}
firstColor; // => 'white'
複製代碼
解構能夠更優雅的實現:spa
const colors = [];
const [firstColor = 'white'] = colors;
firstColor; // => 'white'
複製代碼
const [firstColor = 'white'] = colors
給 firstColor 解構了 colors 數組而後賦值。若是數組沒有任何元素,那麼 默認值是 white
。rest
它還能夠更靈活。若是你只想訪問第二個元素,能夠這樣寫:code
const colors = [];
const [, secondColor = 'black'] = colors;
secondColor; // => 'black'
複製代碼
注意左邊的逗號,它的意思是忽略第一個元素。secondColor
從 colors
數組中的第二項開始指派。
在 react 和 redux 中,咱們經常須要遵循不可變數據的規範。剛開始作可能以爲有點難,以後會發現它的好處:能夠很容易處理無序數據流。
不可變意味着禁止改變對象。解構能夠幫助你在不可變方法中容易地實現某些操做。
解構經過 ...
剩餘操做符來清理數組的第一個元素:
const numbers = [1, 2, 3];
const [, ...fooNumbers] = numbers;
fooNumbers; // => [2, 3]
numbers; // => [1, 2, 3]
複製代碼
解構操做建立了新的數組,注意左邊的逗號,新數組忽略了 numbers 數組的第一個元素。 同時 numbers 保持不變。 一樣的不可變操做能夠從對象中刪除屬性。咱們試試從其餘對象中刪除 foo 屬性。
const big = {
foo: 'value Foo',
bar: 'value Bar'
};
const { foo, ...small } = big;
small; // => { bar: 'value Bar' }
big; // => { foo: 'value Foo', bar: 'value Bar' }
複製代碼
以前的例子都是在數組中。咱們也能夠解構任何對象,來實現迭代控制。
許多原始基本類型和對象能夠迭代。數組,字符串,類數組,set,和 map 等。 好比你能夠解構一個字符串:
const str = 'cheese';
const [firstChar = ''] = str;
firstChar; // => 'c'
複製代碼
沒必要受限於基本類型。解構能夠做用在任何能夠迭代的數據中。
movies 是一個對象。當解構它時,咱們想獲得movie 的 title。來看看下面自定義的迭代:
const movies = {
list: [
{ title: 'Heat' },
{ title: 'Interstellar' }
],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.list.length) {
const value = this.list[index++].title;
return { value, done: false };
}
return { done: true };
}
};
}
};
const [firstMovieTitle] = movies;
console.log(firstMovieTitle); // => 'Heat'
複製代碼
經過定義 Symbol.iterator 來實現迭代協議。該協議遵循解構對象時執行的過程,當經過 const [firstMovieTitle] = movies;
訪問時,只會返回 title。
就我我的經驗,解構對象屬性比解構數組要常見。 解構對象看起來比較簡單:
const movie = { title: 'Heat' };
const { title } = movie;
title; // => 'Heat'
複製代碼
const { title } = movie
建立了一個 title 變量,而後把 movie.title 賦值給了該變量。
你可使用動態屬性名來解構對象。
function greet(obj, nameProp) {
const { [nameProp]: name = 'Unknown' } = obj;
return `Hello, ${name}!`;
}
greet({ name: 'Batman' }, 'name'); // => 'Hello, Batman!'
greet({ }, 'name'); // => 'Hello, Unknown!'
複製代碼
greet 方法調用兩個參數,對象和屬性名。 在 greet 內部,解構賦值讀取了動態屬性名,使用方括號包起來。
更好的方式是添加一個默認值 unknown,以防屬性不存在。
解構在訪問對象屬性和數組元素時,是十分有用的。在上面的例子中,解構在交換變量,訪問元素執行不變對象操做都有體現。你還有什麼其餘的解構方案嗎?請在評論區留言。