重學ES6 解構

legendaryedu發表於2019-04-10

解構:ES6按照一定模式,從陣列和物件中提取值,然後對變數進行賦值。

陣列解構

在之前,我們宣告變數,都是這樣的

let a = 1
let b = 2
let c = 3
複製程式碼

那麼,運用解構,我們可以進行這樣的賦值

let [a, b, c] = [1, 2, 3]
複製程式碼

兩段程式碼的結果是一樣的。

那難道只有這樣嗎???當然不是

當我們想快速的取出某些變數時,只要等號兩邊模式相同,左邊變數就會被右邊賦予相應的值。

我們現在有這樣一組資料,是一個二維陣列,我們想直接拿到二維陣列裡面的值

//[1,[2,3],4,5]
let [a, [b, c], d, e] = [1,[2,3],4,5]
console.log(a) // 1
console.log(b) // 2
console.log(c) // 3
console.log(d) // 4
console.log(e) // 5
複製程式碼

解構也不一定就能成功,也是有前提的。

//如下就會失敗
let [foo] = 1
let [foo] = false
let [foo] = undefined
let [foo] = null
let [foo] = {}
//前五種是 轉為物件之後 不具備 Lterator 介面
//最後一個 是本身就不具備 Lterator 介面
複製程式碼

Lterator 介面:負責遍歷和訪問元素的介面

陣列解構預設值

我們可能在一些情況下,得不到要解構的部分,要採取預設值來填充一些變數。解構賦值也允許我們指定預設值

let [x = 1] = []
//正常情況下,解構是會失敗的,但是賦予了預設值之後,x即為1
複製程式碼

有一點需要注意:只有當 一個陣列元素 ==== undefined時,預設值才會生效

所以,以上程式碼變成

// 預設值不會生效~
let [x = 1] = [null]
// x: null 


let [x = 1] = [undefined]
// x: 1
let [x = 1] = []
// x: 1
複製程式碼

預設值如果是一個表示式,只有當用到這個表示式時,才會去求值。

function g() {
  console.log('get val')
  return 'ok'
}

let [ x = g()] = []

let [ y = g()] = [1]
console.log(x) // 'ok'
console.log(y) // 1  這裡是能夠通過解構直接拿到值的
複製程式碼

物件的解構賦值

先來一個例子看看

let { foo, bar } = { foo: 'hello', bar: 'world'}
console.log( foo ) // hello
console.log( bar ) // world
複製程式碼

這也是一個”模式“,和之前的陣列模式類似

當然,陣列解構可以失敗,物件解構也是一樣的

let { foo } = { bar: 'hahaha'}
console.log( foo ) // undefined
複製程式碼

如果沒有對應的同名屬性,那麼解構失敗,變數值為 undefined

賦值到某個變數

通常我們在使用某個物件的某個方法時,例如console.log,如果使用的頻率相對較高,那麼我們也可以利用物件解構來簡化方法的呼叫

let { log } = console
log( 'hello world' )
複製程式碼

在一些情況下,我們也許有一些別的需求,給方法 設定一個 別名,對應解構出來的某個方法,還是上面的例子,將 log 改名稱 print

let { log:print } = console
print( 'hello world' ) // 'hello world'
複製程式碼

物件解構的預設值

var { x= 3} = {}
x //3

var { y: z = 10 }
z //10
複製程式碼

這裡也是要求 物件的屬性 嚴格等於 === undefined 時,預設值才能生效

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

var {x = 3} = {x: null};
x // null
複製程式碼

字串的解構賦值

const [a,b,c,d,e] = 'hello'
a // 'h'
b // 'e'
c // 'l'
d // 'l'
e // 'o'

let { length : len } = 'hello'
len // 5
複製程式碼

函式引數的解構賦值

注意!!!!如果傳遞了引數那麼實際上就是要為傳遞的實參進行解構賦值,當沒有傳遞實參的時候,才會對函式引數的預設值進行解構賦值!!!

[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [3, 7]
複製程式碼

關於預設值

function move({x = 0, y = 0} = {}) { //此處寫明瞭解構預設值
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
複製程式碼
function move({x, y} = { x: 0, y: 0 }) { // 此處沒有解構預設值
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]  y解構失敗
move({}); // [undefined, undefined] x y 解構失敗
move(); // [0, 0]  沒有傳參,進行解構
複製程式碼

用途

說了半天,也該有點用途了吧

交換變數的值

let x = 1
let y = 2
[x, y] = [y, x]
複製程式碼

從函式返回多個值

function example() {
    return [1, 2, 3]
}

let [a, b, c] = example()
複製程式碼

函式引數定義

//引數有順序,用陣列進行解構
function f([x, y, z]){}
f([1, 2, 3])
//引數無順序,用物件進行解構
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
複製程式碼

提取JSON資料

實際上就是物件解構

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]
複製程式碼

函式引數的預設值

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
} = {}) { //預設解構為{},這樣當傳遞實參進來的時候,屬性為 undefined 就會 得到預設解構的值
  // ... do stuff
};
複製程式碼

遍歷 Map 解構

const map = new Map()
map.set('first','hello')
map.set('second','world')
for (let [key, value] of map) { //每一個元素都是 [key,value] 的結構
    console.log(key + "is" + value)
}

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

// 獲取鍵值
for (let [,value] of map) {
  // ...
}
複製程式碼

輸入模組指定方法

const { SourceMapConsumer, SourceNode } = require("source-map");
複製程式碼

相關文章