2、變量的解構賦值

1、數組的解構賦值

基本用法

本質上,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值,...表示將剩下的值賦予此變量,無剩余則賦值為空數組,解構不成功則賦值為undefined。等號兩邊都要為數組。

let a = 1;
let b = 2;
let c = 3;
//ES6可以寫成
let [a, b, c] = [1, 2, 3];

//多重數組的例子
let [a, [[b], c]] = [1, [[2], 3]];
a // 1
b // 2
c // 3

//對應位置賦予對應的值
let [ , , c] = ["1", "2", "3"];
c // "3"
let [a, , c] = [1, 2, 3];
a // 1
c // 3

//...語法有剩余值時
let [a, ...z] = [1, 2, 3, 4];
a // 1
z // [2, 3, 4]

//...語法無剩余值時
let [a, b, ...z] = ['a'];
a // "a"
b // undefined
z // [] 空數組

默認值

解構賦值可以使用默認值,當且僅當變量的值全等于(===)undefined時,才會使用默認值,即使是等于null時也不會使用默認值。

let [a = 1] = []; a // 1

let [a, b = '2'] = ['1']; // a='1', b='2'
let [a, b = '2'] = ['1', undefined]; // a='1', b='2'

let [x = 1] = [null]; x // null

當默認值是一個表達式的時候(例如一個行數表達式),若變量能夠取到值(值不全等于undefined),則表達式不會執行。

function f() {
  console.log('a');
}
let [x = f()] = [1]; //f()不會執行,y=1

默認值可以引用解構賦值中的其他變量,前提是變量已經聲明

let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // y在x引用的時候還沒有聲明,所以報錯。

2、對象的解構賦值

與數組的解構賦值不同的是,數組解構是按照元素的次序賦值的,而對象則不受次序的影響,變量必須與屬性同名,才能被賦值,沒有同名屬性則賦值為undefined。

let { pro1, pro2 } = { pro1: "1", pro2: "2" };
pro1 // "1"
pro2 // "2"
//上述表述是一種縮寫,其本質是
let { pro1:pro1, pro2:pro2 } = { pro1: "1", pro2: "2" };

//在等號左邊時,:號左邊的pro1和pro2是定義匹配模式,真正被賦值的是:號右邊的pro1和pro2,當匹配模式和屬性名同名時,可以使用縮寫
let { proa:prox, prob:proy } = { proa: "1", prob: "2" };
prox //"1"
proy //"2"

對象解構中左邊的變量一定是由:組成的一對匹配模式和屬性名。只有一個匹配模式時,一定是匹配模式和屬性名相同,使用了簡寫。

var obj= {
  a: {
    b: {
      c: 1,
      d: 2
    }
  }
};
var { a: { b: { c }} } = obj;
a // 報錯,a在:左邊,是匹配模式,不是屬性名
b // 報錯,b在:左邊,是匹配模式,不是屬性名
c // 1

對象的解構賦值同樣支持默認值,規則與數組的解構相似:

  1. 當且僅當變量值全等于(===)undefined時,才會取默認值。
  2. 如果解構失敗,變量的值等于undefined。

當大括號位于本行的首位時,需要加上小括號,因為 { } 表示一個代碼塊,不是一個單獨的語句。

let x;
{x} = {x: 1}; // 語法錯誤,左邊是一個代碼塊,不是一個聲明。

({x} = {x: 1}); // 加上小括號,成為一個單獨的語句,語法正確。

當變量名與現有對象的屬性名相同時,可以直接使用對象賦值。

let { log, sin, cos } = Math;
log // Math.log
sin // Math.sin
cos // Math.cos

因為在JavaScript中,數組是特殊的對象,所以可以用數組進行對象屬性的結構。

let arr = [1, 2, 3];
let {0 : a, [arr.length - 1] : b} = arr;
a // 1
b // 3

3、字符串的解構賦值

字符串進行結構賦值時,被轉化為了一個類似數組的對象。

const [a, b, c, d, e] = 'hello';
a // 'h'
let {length : len} = 'hello';
len // 5   因為右邊'hello'字符串被轉化為了一個類似數組的對象,具有length屬性,所以可以直接賦值給左邊同名的匹配模式。

4、數值和布爾值的解構賦值

解構賦值時,如果等號右邊是數值和布爾值,則會先轉為對象。

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

解構賦值的規則是,只要右邊不是對象或者數組,就將其轉化為對象,再進行匹配賦值。
因為undefined和null不能轉化為對象,所以單獨將這兩個值當做右邊的值進行匹配賦值時會報錯。

let { prop: x } = undefined; // 報錯
let { prop: y } = null; // 報錯

5、函數參數的解構賦值

function add([x, y]){
  return x + y;
}
add([1,2]); // 傳輸數組參數相當于執行了 [x,y]=[1,2];x和y被分別賦值為1和2

函數參數的解構也可以使用默認值,但下面兩種情況不同:

function move({x = 0, y = 0} = {}) {
  return [x, y];
} 

這種方式表示x和y沒有給定值時默認值為0,x和y是分開賦值的,只要參數中存在沒有傳入的項,就使用其默認值。
即只要某一項參數不存在,就一定會使用其默認值。

function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
} 

這種方式指定的是整個參數的默認值,而不是單獨指定x和y,x和y是當做一個整體。只有當完全不傳任何參數時,才會使用默認值(傳入空對象也不會使用默認值),無論是單獨傳了x參數,還是單獨傳了y參數,未傳的項都不會使用默認值。
即只要存在參數,且參數不全等于(===)undefined,就一定不會使用默認值。


6、圓括號問題

ES6的規則是:只要有可能導致解構歧義,就不得使用圓括號。
所以,在非必要情況下,沒有必要添加圓括號(事實上大部分圓括號都是沒有必要添加的)。

不允許使用圓括號的情況
  1. 聲明語句中不允許使用圓括號
  2. 函數參數中,匹配模式不允許使用圓括號,因為函數參數也屬于變量聲明
  3. 不能將整個模式或嵌套中的某一整層放在圓括號當中。

7、解構用途

交換變量的值
let x = 1;
let y = 2;

[x, y] = [y, x]; // 簡潔易懂的交換

從函數返回多個值

當函數需要返回多個值時,將這些值組成一個數組或對象,返回這個數組或對象,然后再用解構賦值來取的各項的值。

// 返回一個數組

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一個對象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

函數參數的定義(包括函數參數使用默認值)
// 參數是一組有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 參數是一組無次序的值
function f({x=0, y=0, z=0}) { ... }
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]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容

  • ES6允許按照一定的模式,從數組和對象中提取值,并對變量進行賦值。這對于解析json數據和函數參數等操作是非常有幫...
    exialym閱讀 543評論 0 2
  • 1.數組的解構賦值 2.對象的解構賦值 3.字符串的解構賦值 4.數值和布爾值的解構賦值 5.函數參數的解構賦值 ...
    卞卞村長L閱讀 919評論 0 0
  • 本文通過學習阮一峰的博客,外加自己的理解,整理了一下我對js變量的解構賦值的理解。 數組的解構賦值 對象的解構賦值...
    宋樂怡閱讀 489評論 0 2
  • 數組的解構賦值 基本用法 ES6允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destru...
    呼呼哥閱讀 435評論 0 3
  • 劉長戰先生是我的小學班主任,從四年級至六年級,舍去其間他被調任初二班主任的半年,我們一起生活了兩年半的動人時光。 ...
    豬鼻子插蔥閱讀 372評論 1 2