你真的瞭解變量的解構賦值嗎(ES6篇)

ES6總結系列之 變量的解構賦值 篇

變量的解構賦值:分解一個對象的結構,對變量進行賦值,前提:等號兩邊的模式相同

數組的解構賦值

可從數組中提取值,按照對應位置,對變量賦值

let [a,b,c] = [1,2,3];
 //a=1,b=2,c=3

let [ , ,c] = [1,2,3]; 
//省略賦值  c=3

let [a, [[b], c]] = [1, [[2], 3]];
//嵌套解構 a=1,c=2,c=3

let [a] = [];
//結構不成功,變量的的值就等於undefined, 所以a = undefined

let [x = 1,j = 1] = [undefined, null];
//x = 1; j = null;
//解構指定默認值, 只有嚴格等於(===)undefined是才起作用

//默認值爲表達式時,其求值時惰性的,即需要用時才計算,如下
function f() {
  console.log('aaa');
}
let [x = f()] = [1];
//上面代碼中,因爲x能取到值,所以函數f根本不會執行。

let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError: y is not defined
默認值可以引用解構賦值的其他變量,但該變量必須已經聲明
//上面最後一個表達式之所以會報錯,是因爲x用y做默認值時,y還沒有聲明。

對象的解構賦值

對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
//foo = 'aaa';  bar = 'bbb';

//變量名與屬性名不一樣,應寫成
let { foo : a, bar : b } = { foo: 'aaa', bar: 'bbb' };
//a = 'aaa'; b = 'bbb'
//foo = undefined; bar = underfined;
//對象的解構賦值的內部機制,是先找到同名屬性,然後再賦給對應的變量。真正被賦值的是後者,而不是前者

let { baz } = { foo: 'aaa', bar: 'bbb' };
//baz = undefined  找不到名爲baz的屬性

var {x: y = 3} = {};
//y = 3  指定默認值

字符串的解構賦值

字符串也可以解構賦值。這是因爲此時,字符串被轉換成了一個類似數組的對象。

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

類似數組的對象都有一個length屬性,因此還可以對這個屬性解構賦值。
let {length : len} = 'hello';
len // 5

數值和布爾值的解構賦值

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

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

上面代碼中,數值和布爾值的包裝對象都有toString屬性,因此變量s都能取到值。

函數參數的解構賦值

function add([x, y]){
  return x + y;})
add([1, 2]; // 3

上面代碼中,函數add的參數表面上是一個數組,但在傳入參數的那一刻,數組參數就被解構成變量x和y。對於函數內部的代碼來說,它們能感受到的參數就是x和y。

圓括號問題

let x;
{x} = {x: 1};
// SyntaxError: syntax error

// 特別注意,當大括號位於行首時,JavaScript 引擎會將{x}理解成一個代碼塊,從而發生語法錯誤。,可通過加圓括號解決,如下

let x;
({x} = {x: 1});
僅賦值語句的非模式部分,可以使用圓括號。

[(b)] = [3]; // 正確
({ p: (d) } = {}); // 正確
[(parseInt.prop)] = [3]; // 正確

總結要點

  • 解構賦值本質對象的解構,只要等號右邊的值不是對象或數組,就先將其轉爲對象。由於undefinednull無法轉爲對象,所以對它們進行解構賦值,都會報錯。
  • 只要某種數據結構具有 Iterator 接口,就可以用於數組的解構賦值,如arguments類數組對象,NodeList類數組對象
  • 對象的解構賦值可以取到繼承的屬性
  • 默認值生效的條件是,解構的值嚴格等於undefined
  • 僅賦值語句的非模式部分,可以使用圓括號。

  • ES6總結系列參考自阮一峯大神的《ECMAScript6入門》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章