ES6解構(gòu)賦值(數(shù)組,對(duì)象,函數(shù))使用詳解
解構(gòu)賦值
JavaScript 中最常用的兩種數(shù)據(jù)結(jié)構(gòu)是 Object 和 Array。
- 對(duì)象讓我們能夠創(chuàng)建通過(guò)鍵來(lái)存儲(chǔ)數(shù)據(jù)項(xiàng)的單個(gè)實(shí)體。
- 數(shù)組則讓我們能夠?qū)?shù)據(jù)收集到一個(gè)有序的集合中。
但是,當(dāng)我們把它們傳遞給函數(shù)時(shí),函數(shù)可能不需要整個(gè)對(duì)象/數(shù)組。它可能只需要對(duì)象/數(shù)組的一部分。
解構(gòu)賦值 是一種特殊的語(yǔ)法,它使我們可以將數(shù)組或?qū)ο?ldquo;拆包”至一系列變量中,因?yàn)橛袝r(shí)這樣更方便。
解構(gòu)操作對(duì)那些具有很多參數(shù)和默認(rèn)值等的函數(shù)也很奏效。我們馬上會(huì)看到類似的例子。
數(shù)組解構(gòu)
下面是一個(gè)將數(shù)組解構(gòu)到變量中的例子:
// 我們有一個(gè)存放了名字和姓氏的數(shù)組 let arr = ["John", "Smith"] // 解構(gòu)賦值 // sets firstName = arr[0] // and surname = arr[1] let [firstName, surname] = arr; alert(firstName); // John alert(surname); // Smith
現(xiàn)在我們就可以針對(duì)這些變量進(jìn)行操作,而不是針對(duì)原來(lái)的數(shù)組元素。
當(dāng)與 split 函數(shù)(或其他返回值是數(shù)組的函數(shù))結(jié)合使用時(shí),看起來(lái)就更優(yōu)雅了:
let [firstName, surname] = "John Smith".split(' ');
alert(firstName); // John
alert(surname); // Smith正如我們所看到的,語(yǔ)法很簡(jiǎn)單。但是有幾個(gè)需要注意的細(xì)節(jié)。讓我們通過(guò)更多的例子來(lái)加深理解。
“解構(gòu)”并不意味著“破壞”
這種語(yǔ)法叫做“解構(gòu)賦值”,因?yàn)樗ㄟ^(guò)將結(jié)構(gòu)中的各元素復(fù)制到變量中來(lái)達(dá)到“解構(gòu)”的目的。但數(shù)組本身是沒(méi)有被修改的。
這只是下面這些代碼的更精簡(jiǎn)的寫(xiě)法而已:
// let [firstName, surname] = arr; let firstName = arr[0]; let surname = arr[1];
忽略使用逗號(hào)的元素
數(shù)組中不想要的元素也可以通過(guò)添加額外的逗號(hào)來(lái)把它丟棄:
// 不需要第二個(gè)元素 let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; alert( title ); // Consul
在上面的代碼中,數(shù)組的第二個(gè)元素被跳過(guò)了,第三個(gè)元素被賦值給了
title變量,數(shù)組中剩下的元素也都被跳過(guò)了(因?yàn)樵谶@沒(méi)有對(duì)應(yīng)給它們的變量)。
等號(hào)右側(cè)可以是任何可迭代對(duì)象
……實(shí)際上,我們可以將其與任何可迭代對(duì)象一起使用,而不僅限于數(shù)組:
let [a, b, c] = "abc"; // ["a", "b", "c"] let [one, two, three] = new Set([1, 2, 3]);
這行得通,因?yàn)樵趦?nèi)部,結(jié)構(gòu)賦值是通過(guò)迭代右側(cè)的值來(lái)完成工作的。這是一種用于對(duì)在
=右側(cè)的值上調(diào)用for..of并進(jìn)行賦值的操作的語(yǔ)法糖。
賦值給等號(hào)左側(cè)的任何內(nèi)容
我們可以在等號(hào)左側(cè)使用任何“可以被賦值的”東西。
例如,一個(gè)對(duì)象的屬性:
let user = {};
[user.name, user.surname] = "John Smith".split(' ');
alert(user.name); // John
alert(user.surname); // Smith與 .entries() 方法進(jìn)行循環(huán)操作
在前面的章節(jié)中我們已經(jīng)見(jiàn)過(guò)了 Object.entries(obj) 方法。
我們可以將 .entries() 方法與解構(gòu)語(yǔ)法一同使用,來(lái)遍歷一個(gè)對(duì)象的“鍵—值”對(duì):
let user = {
name: "John",
age: 30
};
// 循環(huán)遍歷鍵—值對(duì)
for (let [key, value] of Object.entries(user)) {
alert(`${key}:${value}`); // name:John, then age:30
}用于
Map的類似的代碼更簡(jiǎn)單,因?yàn)樗强傻模?/p>
let user = new Map();
user.set("name", "John");
user.set("age", "30");
// Map 是以 [key, value] 對(duì)的形式進(jìn)行迭代的,非常便于解構(gòu)
for (let [key, value] of user) {
alert(`${key}:${value}`); // name:John, then age:30
}交換變量值的技巧
有一個(gè)著名的使用結(jié)構(gòu)賦值來(lái)交換兩個(gè)變量的值的技巧:
let guest = "Jane";
let admin = "Pete";
// 讓我們來(lái)交換變量的值:使得 guest = Pete,admin = Jane
[guest, admin] = [admin, guest];
alert(`${guest} ${admin}`); // Pete Jane(成功交換?。?/pre>這里我們創(chuàng)建了一個(gè)由兩個(gè)變量組成的臨時(shí)數(shù)組,并且立即以交換了的順序?qū)ζ溥M(jìn)行了解構(gòu)。
我們可以用這種方式交換兩個(gè)以上的變量。
其余的 ‘…’
通常,如果數(shù)組比左邊的列表長(zhǎng),那么“其余”的數(shù)組項(xiàng)會(huì)被省略。
例如,這里只取了兩項(xiàng),其余的就被忽略了:
let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; alert(name1); // Julius alert(name2); // Caesar // 其余數(shù)組項(xiàng)未被分配到任何地方
如果我們還想收集其余的數(shù)組項(xiàng) —— 我們可以使用三個(gè)點(diǎn) "..." 來(lái)再加一個(gè)參數(shù)以獲取“其余”數(shù)組項(xiàng):
let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; // rest 是包含從第三項(xiàng)開(kāi)始的其余數(shù)組項(xiàng)的數(shù)組 alert(rest[0]); // Consul alert(rest[1]); // of the Roman Republic alert(rest.length); // 2
rest 的值就是數(shù)組中剩下的元素組成的數(shù)組。
不一定要使用變量名 rest,我們也可以使用任何其他的變量名,只要確保它前面有三個(gè)點(diǎn),并且在解構(gòu)賦值的最后一個(gè)參數(shù)位置上就行了。
let [name1, name2, ...titles] = ["Julius", "Caesar", "Consul", "of the Roman Republic"]; // 現(xiàn)在 titles = ["Consul", "of the Roman Republic"]
默認(rèn)值
如果數(shù)組比左邊的變量列表短,這里也不會(huì)出現(xiàn)報(bào)錯(cuò)。缺少的值被認(rèn)為是 undefined:
let [firstName, surname] = []; alert(firstName); // undefined alert(surname); // undefined
如果我們想要一個(gè)“默認(rèn)”值給未賦值的變量,我們可以使用 = 來(lái)提供:
// 默認(rèn)值 let [name = "Guest", surname = "Anonymous"] = ["Julius"]; alert(name); // Julius(來(lái)自數(shù)組的值) alert(surname); // Anonymous(默認(rèn)值被使用了)
默認(rèn)值可以是更加復(fù)雜的表達(dá)式甚至可以是函數(shù)調(diào)用,這些表達(dá)式或函數(shù)只會(huì)在這個(gè)變量未被賦值的時(shí)候才會(huì)被計(jì)算。
舉個(gè)例子,我們使用了 prompt 函數(shù)來(lái)提供兩個(gè)默認(rèn)值:
// 只會(huì)提示輸入姓氏
let [name = prompt('name?'), surname = prompt('surname?')] = ["Julius"];
alert(name); // Julius(來(lái)自數(shù)組)
alert(surname); // 你輸入的值請(qǐng)注意:prompt 將僅針對(duì)缺失值(surname)運(yùn)行。
對(duì)象解構(gòu)
解構(gòu)賦值同樣適用于對(duì)象。
基本語(yǔ)法是:
let {var1, var2} = {var1:…, var2:…}在等號(hào)右側(cè)應(yīng)該有一個(gè)已經(jīng)存在的對(duì)象,我們想把它拆分到變量中。等號(hào)左側(cè)包含了對(duì)象相應(yīng)屬性的一個(gè)類對(duì)象“模式(pattern)”。在最簡(jiǎn)單的情況下,等號(hào)左側(cè)的就是 {...} 中的變量名列表。
舉個(gè)例子:
let options = {
title: "Menu",
width: 100,
height: 200
};
let {title, width, height} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200屬性 options.title、options.width 和 options.height 值被賦給了對(duì)應(yīng)的變量。
變量的順序并不重要,下面這個(gè)代碼也奏效:
// 改變 let {...} 中元素的順序
let {height, width, title} = { title: "Menu", height: 200, width: 100 }等號(hào)左側(cè)的模式(pattern)可以更加復(fù)雜,并且指定了屬性和變量之間的映射關(guān)系。
如果我們想把一個(gè)屬性賦值給另一個(gè)名字的變量,比如把 options.width 屬性賦值給名為 w 的變量,那么我們可以使用冒號(hào)來(lái)設(shè)置變量名稱:
let options = {
title: "Menu",
width: 100,
height: 200
};
// { sourceProperty: targetVariable }
let {width: w, height: h, title} = options;
// width -> w
// height -> h
// title -> title
alert(title); // Menu
alert(w); // 100
alert(h); // 200冒號(hào)表示“什么值:賦值給誰(shuí)”。上面的例子中,屬性 width 被賦值給了 w,屬性 height 被賦值給了 h,屬性 title 被賦值給了同名變量。
對(duì)于可能缺失的屬性,我們可以使用 "=" 設(shè)置默認(rèn)值,如下所示:
let options = {
title: "Menu"
};
let {width = 100, height = 200, title} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200就像數(shù)組或函數(shù)參數(shù)一樣,默認(rèn)值可以是任意表達(dá)式甚至可以是函數(shù)調(diào)用。它們只會(huì)在未提供對(duì)應(yīng)的值時(shí)才會(huì)被計(jì)算/調(diào)用。
在下面的代碼中,prompt 提示輸入 width 值,但不會(huì)提示輸入 title 值:
let options = {
title: "Menu"
};
let {width = prompt("width?"), title = prompt("title?")} = options;
alert(title); // Menu
alert(width); // (prompt 的返回值)我們還可以將冒號(hào)和等號(hào)結(jié)合起來(lái):
let options = {
title: "Menu"
};
let {width: w = 100, height: h = 200, title} = options;
alert(title); // Menu
alert(w); // 100
alert(h); // 200如果我們有一個(gè)具有很多屬性的復(fù)雜對(duì)象,那么我們可以只提取所需的內(nèi)容:
let options = {
title: "Menu",
width: 100,
height: 200
};
// 僅提取 title 作為變量
let { title } = options;
alert(title); // Menu剩余模式(pattern)"…"
如果對(duì)象擁有的屬性數(shù)量比我們提供的變量數(shù)量還多,該怎么辦?我們可以只取其中的某一些屬性,然后把“剩余的”賦值到其他地方嗎?
我們可以使用剩余模式(pattern),就像我們對(duì)數(shù)組那樣。一些較舊的瀏覽器不支持此功能(例如,使用 Babel 對(duì)其進(jìn)行填充),但可以在現(xiàn)代瀏覽器中使用。
看起來(lái)就像這樣:
let options = {
title: "Menu",
height: 200,
width: 100
};
// title = 名為 title 的屬性
// rest = 存有剩余屬性的對(duì)象
let {title, ...rest} = options;
// 現(xiàn)在 title="Menu", rest={height: 200, width: 100}
alert(rest.height); // 200
alert(rest.width); // 100
let options = {
title: "Menu",
height: 200,
width: 100
};
// title = 名為 title 的屬性
// rest = 存有剩余屬性的對(duì)象
let {title, ...rest} = options;
// 現(xiàn)在 title="Menu", rest={height: 200, width: 100}
alert(rest.height); // 200
alert(rest.width); // 100不使用
let時(shí)的陷阱在上面的示例中,變量都是在賦值中通過(guò)正確方式聲明的:
let {…} = {…}。當(dāng)然,我們也可以使用已有的變量,而不用let,但這里有一個(gè)陷阱。以下代碼無(wú)法正常運(yùn)行:
let title, width, height;
// 這一行發(fā)生了錯(cuò)誤
{title, width, height} = {title: "Menu", width: 200, height: 100};問(wèn)題在于 JavaScript 把主代碼流(即不在其他表達(dá)式中)的
{...}當(dāng)做一個(gè)代碼塊。這樣的代碼塊可以用于對(duì)語(yǔ)句分組,如下所示:
{
// 一個(gè)代碼塊
let message = "Hello";
// ...
alert( message );
}因此,這里 JavaScript 假定我們有一個(gè)代碼塊,這就是報(bào)錯(cuò)的原因。我們需要解構(gòu)它。
為了告訴 JavaScript 這不是一個(gè)代碼塊,我們可以把整個(gè)賦值表達(dá)式用括號(hào)
(...)包起來(lái):
let title, width, height;
// 現(xiàn)在就可以了
({title, width, height} = {title: "Menu", width: 200, height: 100});
alert( title ); // Menu嵌套解構(gòu)
如果一個(gè)對(duì)象或數(shù)組嵌套了其他的對(duì)象和數(shù)組,我們可以在等號(hào)左側(cè)使用更復(fù)雜的模式(pattern)來(lái)提取更深層的數(shù)據(jù)。
在下面的代碼中,options 的屬性 size 是另一個(gè)對(duì)象,屬性 items 是另一個(gè)數(shù)組。賦值語(yǔ)句中等號(hào)左側(cè)的模式(pattern)具有相同的結(jié)構(gòu)以從中提取值:
let options = {
size: {
width: 100,
height: 200
},
items: ["Cake", "Donut"],
extra: true
};
// 為了清晰起見(jiàn),解構(gòu)賦值語(yǔ)句被寫(xiě)成多行的形式
let {
size: { // 把 size 賦值到這里
width,
height
},
items: [item1, item2], // 把 items 賦值到這里
title = "Menu" // 在對(duì)象中不存在(使用默認(rèn)值)
} = options;
alert(title); // Menu
alert(width); // 100
alert(height); // 200
alert(item1); // Cake
alert(item2); // Donut對(duì)象 options 的所有屬性,除了 extra 屬性在等號(hào)左側(cè)不存在,都被賦值給了對(duì)應(yīng)的變量:

最終,我們得到了 width、height、item1、item2 和具有默認(rèn)值的 title 變量。
注意,size 和 items 沒(méi)有對(duì)應(yīng)的變量,因?yàn)槲覀內(nèi)〉氖撬鼈兊膬?nèi)容。
智能函數(shù)參數(shù)
有時(shí),一個(gè)函數(shù)有很多參數(shù),其中大部分的參數(shù)都是可選的。對(duì)用戶界面來(lái)說(shuō)更是如此。想象一個(gè)創(chuàng)建菜單的函數(shù)。它可能具有寬度參數(shù),高度參數(shù),標(biāo)題參數(shù)和項(xiàng)目列表等。
下面是實(shí)現(xiàn)這種函數(shù)的一個(gè)很不好的寫(xiě)法:
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
// ...
}在實(shí)際開(kāi)發(fā)中存在一個(gè)問(wèn)題就是你怎么記得住這么多參數(shù)的順序。通常集成開(kāi)發(fā)環(huán)境工具(IDE)會(huì)盡力幫助我們,特別是當(dāng)代碼有良好的文檔注釋的時(shí)候,但是…… 另一個(gè)問(wèn)題就是,當(dāng)大部分的參數(shù)采用默認(rèn)值就好的情況下,怎么調(diào)用這個(gè)函數(shù)。
難道像這樣?
// 在采用默認(rèn)值就可以的位置設(shè)置 undefined
showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])這太難看了。而且,當(dāng)我們處理更多參數(shù)的時(shí)候可讀性會(huì)變得很差。
解構(gòu)賦值語(yǔ)法前來(lái)救援!
我們可以把所有參數(shù)當(dāng)作一個(gè)對(duì)象來(lái)傳遞,然后函數(shù)馬上把這個(gè)對(duì)象解構(gòu)成多個(gè)變量:
// 我們傳遞一個(gè)對(duì)象給函數(shù)
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
// ……然后函數(shù)馬上把對(duì)象展開(kāi)成變量
function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
// title, items – 提取于 options,
// width, height – 使用默認(rèn)值
alert( `${title} ${width} ${height}` ); // My Menu 200 100
alert( items ); // Item1, Item2
}
showMenu(options);我們同樣可以使用帶有嵌套對(duì)象和冒號(hào)映射的更加復(fù)雜的解構(gòu):
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
function showMenu({
title = "Untitled",
width: w = 100, // width goes to w
height: h = 200, // height goes to h
items: [item1, item2] // items first element goes to item1, second to item2
}) {
alert( `${title} ${w} ${h}` ); // My Menu 100 200
alert( item1 ); // Item1
alert( item2 ); // Item2
}
showMenu(options);完整語(yǔ)法和解構(gòu)賦值是一樣的:
function({
incomingProperty: varName = defaultValue
...
})對(duì)于參數(shù)對(duì)象,屬性 incomingProperty 對(duì)應(yīng)的變量是 varName,默認(rèn)值是 defaultValue。
請(qǐng)注意,這種解構(gòu)假定了 showMenu() 函數(shù)確實(shí)存在參數(shù)。如果我們想讓所有的參數(shù)都使用默認(rèn)值,那我們應(yīng)該傳遞一個(gè)空對(duì)象:
showMenu({}); // 不錯(cuò),所有值都取默認(rèn)值
showMenu(); // 這樣會(huì)導(dǎo)致錯(cuò)誤我們可以通過(guò)指定空對(duì)象 {} 為整個(gè)參數(shù)對(duì)象的默認(rèn)值來(lái)解決這個(gè)問(wèn)題:
function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
alert( `${title} ${width} ${height}` );
}
showMenu(); // Menu 100 200在上面的代碼中,整個(gè)參數(shù)對(duì)象的默認(rèn)是 {},因此總會(huì)有內(nèi)容可以用來(lái)解構(gòu)。
總結(jié)
- 解構(gòu)賦值可以立即將一個(gè)對(duì)象或數(shù)組映射到多個(gè)變量上。
- 解構(gòu)對(duì)象的完整語(yǔ)法:
let {prop : varName = default, ...rest} = object這表示屬性 prop 會(huì)被賦值給變量 varName,如果沒(méi)有這個(gè)屬性的話,就會(huì)使用默認(rèn)值 default。
沒(méi)有對(duì)應(yīng)映射的對(duì)象屬性會(huì)被復(fù)制到 rest 對(duì)象。
解構(gòu)數(shù)組的完整語(yǔ)法:
let [item1 = default, item2, ...rest] = array
數(shù)組的第一個(gè)元素被賦值給 item1,第二個(gè)元素被賦值給 item2,剩下的所有元素被復(fù)制到另一個(gè)數(shù)組 rest。
從嵌套數(shù)組/對(duì)象中提取數(shù)據(jù)也是可以的,此時(shí)等號(hào)左側(cè)必須和等號(hào)右側(cè)有相同的結(jié)構(gòu)。
引用地址:解構(gòu)賦值
到此這篇關(guān)于ES6解構(gòu)賦值(數(shù)組,對(duì)象,函數(shù))使用詳解的文章就介紹到這了,更多相關(guān)ES6解構(gòu)賦值使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript動(dòng)態(tài)設(shè)置div的樣式的方法
這篇文章主要介紹了JavaScript動(dòng)態(tài)設(shè)置div的樣式的方法的相關(guān)資料,需要的朋友可以參考下2015-12-12
JS對(duì)img進(jìn)行操作(換圖片/切圖/輪換/停止)
JS對(duì)img進(jìn)行操作包括:換圖片/切圖/輪換/停止輪換等等,在本文將逐一實(shí)現(xiàn),感興趣的朋友可以參考下哈,希望對(duì)你學(xué)習(xí)js知識(shí)有所幫助2013-04-04
JS實(shí)現(xiàn)自動(dòng)固定頂部的懸浮菜單欄效果
這篇文章主要介紹了JS實(shí)現(xiàn)自動(dòng)固定頂部的懸浮菜單欄效果,涉及JavaScript針對(duì)window.onscroll事件的響應(yīng)及頁(yè)面樣式動(dòng)態(tài)變換的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
用Javascript實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼間隔功能
這篇文章主要介紹了用Javascript實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼間隔功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
如何使用ImageDecoder API讓GIF圖片暫停播放
在本文中,我們介紹了如何使用ImageDecoder API來(lái)暫停GIF圖像的播放,雖然這需要一些JavaScript編程知識(shí),但它是一個(gè)非常強(qiáng)大的技術(shù),可以讓您對(duì)GIF圖像進(jìn)行各種高級(jí)操作,感興趣的朋友跟隨小編一起看看吧2023-06-06
JS實(shí)現(xiàn)數(shù)組去重復(fù)值的方法示例
這篇文章主要介紹了JS實(shí)現(xiàn)數(shù)組去重復(fù)值的方法,結(jié)合實(shí)例形式分析了JS通過(guò)數(shù)組遍歷、運(yùn)算等方法實(shí)現(xiàn)去重復(fù)值的操作技巧,需要的朋友可以參考下2017-02-02
js實(shí)現(xiàn)搜索框關(guān)鍵字智能匹配代碼
這篇文章主要為大家分享了js實(shí)現(xiàn)搜索框關(guān)鍵字智能匹配代碼,感興趣的朋友可以參考一下2016-01-01

