5個JavaScript 解構的有趣用法

原文:Dmitri Pavlutin

翻譯:瘋狂的技術宅javascript

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

未經容許嚴禁轉載java

若是你查看個人常規 JavaScript 代碼,會看到處處都有解構。程序員

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

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

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. 訪問數組項

假設你有一系列可能爲空的項目。你要訪問數組的第1、第二或第 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 提供了更大的可能性,由於你能夠用迭代器自定義解構邏輯。

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


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

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

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

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


相關文章
相關標籤/搜索