5個JavaScript 解構的有趣用法

原文:Dmitri Pavlutin

翻譯:瘋狂的技術宅

原文:https://dmitripavlutin.com/5-...

未經允許嚴禁轉載

如果你查看我的常規 JavaScript 代碼,會看到到處都有解構。

讀取對象屬性和訪問數組項是常見的操作。結構使這些操作變得更加輕鬆和簡潔。

在本文中,除了基本用法之外,我還將會介紹在 JavaScript 中 5 種有趣的解構用法。

1. 交換變量

通常交換兩個變量的方法需要一個附加的臨時變量。讓我們看一個簡單的場景:

let a = 1;
let b = 2;
let temp;

temp = a;
a = b;
b = temp;

a; // => 2
b; // => 1

temp 是保存 a 的值的臨時變量。然後,爲 a 分配 b 的值,最後爲 b 分配 temp 的值。

解構分配使變量交換變得簡單,不需要任何臨時變量:

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

儘管仍會創建臨時數組,但使用解構分配交換變量更爲簡潔。

這不是極限。你可以同時交換兩個以上的變量。讓我們嘗試一下:

let zero = 2;
let one = 1;
let two = 0;

[zero, one, two] = [two, one, zero];

zero; // => 0
one;  // => 1
two;  // => 2

你可以根據需要交換任意多個變量!雖然交換兩個變量是最常見的操作。

2. 訪問數組項

假設你有一系列可能爲空的項目。你要訪問數組的第一、第二或第 n 個項目,但是如果該項目不存在,請獲取默認值。

通常你會用到數組的 length 屬性:

const colors = [];

let firstColor = 'white';
if (colors.length > 0) {
 firstColor = colors[0];
}

firstColor; // => 'white'

幸運的是,數組解構可以幫助你實現更短的操作代碼:

const colors = [];

const [firstColor = 'white'] = colors;

firstColor; // => 'white'

const [firstColor ='white'] = colors 解構將 colors 數組的第一個元素分配給 firstColor 變量。如果數組在索引 0 處沒有任何元素,則將分配默認值 white

但是這有更多的靈活性。如果你只想訪問第二個元素,也可以這樣:

const colors = [];

const [, secondColor = 'black'] = colors;

secondColor; // => 'black'

注意結構左側的逗號:這意味着第一個元素將被忽略。從 color 數組中爲索引爲 1 的元素分配了 secondColor

3.不變的操作

當我開始用 React 以及後來的 Redux 時,被迫編寫尊重不變性的代碼。儘管一開始遇到了一些困難,但後來我看到了它的好處:單向數據流更容易處理。

不變性禁止更改對象。幸運的是,解構可以幫你輕鬆地以不變的方式完成某些操作。

結合使用 ... rest 操作符可以從數組的開頭刪除元素:

const numbers = [1, 2, 3];

const [, ...fooNumbers] = numbers;

fooNumbers; // => [2, 3]
numbers; // => [1, 2, 3]

解構 [, ...fooNumbers] = numbers 將創建一個新的數組 fooNumbers,其中包含來自 numbers 的項目,除了第一項。

numbers 數組不會發生變異,從而使操作保持不變。

你可以以不變的方式從對象中刪除屬性。讓我們嘗試從對象 big 中刪除 foo 屬性:

const big = {
 foo: 'value Foo',
 bar: 'value Bar'
};

const { foo, ...small } = big;

small; // => { bar: 'value Bar' }
big; // => { foo: 'value Foo', bar: 'value Bar' }

解構與 object rest operator 結合使用可創建一個具有 big 所有屬性的新對象 small ,唯獨不包含 foo

4. 解構可迭代對象

在前面的章節中,我們將解構應用於數組。但是你可以解構實現了可迭代協議的任何對象。

許多原生原始類型和對象都是可迭代的:數組、字符串、類型化數組、集合和映射。

例如,你可以將字符串分解爲字符:

const str = 'cheese';

const [firstChar = ''] = str;

firstChar; // => 'c'

不僅限於原生類型,也可以通過實現可迭代協議來自定義解構邏輯。

movies 擁有電影對象的列表。解構 movies 時,最好將電影標題作爲字符串。讓我們實現一個自定義迭代器:

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'

movies 對象通過定義 Symbol.iterator 方法來實現可迭代的協議。迭代器遍歷電影的標題。

遵循可迭代協議,可以將 movies 對象結構爲標題,特別是通過讀取第一部電影的標題: const [firstMovieTitle] = movies

在使用迭代器進行解構時,只有天空纔是對你的限制。

5. 解構動態屬性

以我的經驗,通過屬性對對象進行解構比對數組進行解構更爲常見。

對象的解構看起來非常簡單:

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() 內部,解構賦值 const {[nameProp]:name ='Unknown'} = obj 使用方括號 [nameProp] 讀取動態屬性名稱。變量 name 接收動態屬性值。

更妙的是如果該屬性不存在,則可以指定默認值 'Unknown'

六. 結論

如果要訪問對象屬性和數組項,則解構效果很好。

除了基本用法外,數組解構還可以方便地交換變量、訪問數組項、執行一些不可變的操作。

JavaScript 提供了更大的可能性,因爲你可以用迭代器自定義解構邏輯。

你知道還有哪些關於解構有趣的應用?在下面寫評論!


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章