解構(gòu)
ES6 允許按照一定模式肪获,從數(shù)組和對象中提取值润匙,對變量進(jìn)行賦值
數(shù)組解構(gòu)賦值
- 本質(zhì)上這種寫法相當(dāng)于模式匹配
如果解析不成功那么變量的值就等于undefined
let [a,b,c] = [1,2,3];
//a=1,b=2,c=3;
let [foo,baz] = [0];
//foo=0, baz=undefined;
- 不完全解構(gòu),即等號(hào)左邊的模式只匹配等號(hào)右邊的一部分模式添坊,這樣的解構(gòu)也能夠成功
let [a,b,c] = [1,2,3,4];
//a=1,b=2,c=3;
- 如果等號(hào)右邊不是可遍歷結(jié)構(gòu)時(shí)則會(huì)報(bào)錯(cuò)
let [foo] = 1;
let [baz]={};
- 默認(rèn)值
一個(gè)數(shù)組成員不嚴(yán)格等于undefined太伊,默認(rèn)值是不會(huì)生效的雇锡。
let [foo=1]=[];
//foo = 1;
let [foo=1] = [2];
//foo = 2;
let [baz = 3] = [null];
//baz=null;
*null不嚴(yán)格等于undefined*
如果默認(rèn)值是一個(gè)表達(dá)式則這個(gè)表達(dá)式是惰性求值的,只有在用到時(shí)才會(huì)求值
function f() {
console.log('aaa');
}
let [x = f()] = [1];
// x= 1;
let [y = f()] = [];
//y=aaa;
默認(rèn)值可以引用解構(gòu)賦值的其他變量,前提是該變量已聲明
let [x = 1, y = x] = []; // x=1; y=1
let [x = y, y = 1] = []; // ReferenceError
對象解構(gòu)賦值
- 對象的屬性沒有次序僚焦,變量必須與屬性同名锰提,才能取到正確的值
let {foo,baz} = {baz:'aaa',foo:'bbb'};
//foo='bbb', baz = 'aaa'
當(dāng)變量和屬性名不同時(shí)可以這樣寫
let {foo:baz} = {foo:'aaa'};
baz; //aaa
*foo 為匹配模式,baz才是變量*
對象的解構(gòu)賦值的內(nèi)部機(jī)制芳悲,是先找到同名屬性立肘,然后再賦給對應(yīng)的變量。真正被賦值的是后者名扛,而不是前者赛不。
- 默認(rèn)值的產(chǎn)生條件是,對象的屬性值嚴(yán)格等于undefined
- 如果解構(gòu)失敗則變量的值等于undefined
- 可以將一個(gè)已聲明的變量用于結(jié)構(gòu)賦值
//錯(cuò)誤寫法
let x;
{x} = {x:1};
//正確寫法
let x;
({x} = {x: 1});
JavaScript 引擎會(huì)將{x}理解成一個(gè)代碼塊罢洲,從而發(fā)生語法錯(cuò)誤踢故。只有不將大括號(hào)寫在行首文黎,避免javarscript將其解釋為代碼塊
字符串解析賦值
將字符串轉(zhuǎn)換為一個(gè)類似數(shù)組的對象
let [a,b,c,d] = 'good';
//a= 'g' b='o' c='o' d='d'
類似數(shù)組的對象都有一個(gè)length屬性,因此還可以對這個(gè)屬性解構(gòu)賦值殿较。
let {length : len} = 'hello';
len // 5
數(shù)值和布爾值解構(gòu)賦值
- 解構(gòu)賦值時(shí)耸峭,如果等號(hào)右邊是數(shù)值和布爾值,則會(huì)先轉(zhuǎn)為對象
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
只要等號(hào)右邊的值不是對象或數(shù)組淋纲,就先將其轉(zhuǎn)為對象,null和undefined無法轉(zhuǎn)換為對象劳闹,當(dāng)?shù)忍?hào)右邊為null / undefined時(shí)會(huì)報(bào)錯(cuò)
函數(shù)參數(shù)解構(gòu)賦值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
- 函數(shù)參數(shù)解構(gòu)賦值也可以使用默認(rèn)值,同時(shí)undefined觸發(fā)默認(rèn)值
?
對于編譯器來說洽瞬,一個(gè)式子到底是模式本涕,還是表達(dá)式,沒有辦法從一開始就知道伙窃,必須解析到(或解析不到)等號(hào)才能知道菩颖。當(dāng)模式中出現(xiàn)圓括號(hào)時(shí)es6遵守只要有可能導(dǎo)致解構(gòu)的歧義,就不得使用圓括號(hào)的原則
不能使用圓括號(hào)的時(shí)候
1.變量聲明 2.函數(shù)參數(shù) 3.賦值語句的模式
使用圓括號(hào)的時(shí)候
賦值語句的非模式部分
使用場所
(1)交換變量的值
var x=1;
var y=2;
[x,y] = [y,x];
(2)從函數(shù)返回多個(gè)值
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
(3)函數(shù)參數(shù)的定義
function example ([x,y,z]){
...
}
example([1,2,3]);
(4)提取JSON數(shù)據(jù)
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
(5)函數(shù)參數(shù)的默認(rèn)值
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
}) {
// ... do stuff
};
(6)遍歷Map結(jié)構(gòu)
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
(7)輸入模塊的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");