解構: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");
複製程式碼