[TOC]
>[success] # 數組的解構賦值
<br/>
>[success] ## 基本用法
ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構。
以前,為變量賦值,只能直接指定值。
~~~
let a = 1;
let b = 2;
let c = 3;
~~~
ES6 允許寫成下面這樣,這種寫法為匹配模式,只要`=`兩邊的模式相同,左邊的變量就會被賦予對應的值。
~~~
let [a, b, c] = [1, 2, 3];
console.log( a ) // 1
console.log( b ) // 2
console.log( c ) // 3
~~~
<br/>
>[success] ## 嵌套數組
第一種寫法,按照數組的格式來嵌套就可以取出來對應的數據
~~~
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log( foo ) // 1
console.log( bar ) // 2
console.log( baz ) // 3
~~~
第二種寫法,即使左側的一些值未定義逗號分隔還在,也是可以的
~~~
let [ , , third] = ["foo", "bar", "baz"];
console.log( third ) // "baz"
~~~
第三種寫法,配合擴展運算符
~~~
let [head, ...tail] = [1, 2, 3, 4];
console.log( head ) // "1"
console.log( tail ) // [2, 3, 4]
~~~
<br/>
>[danger] ## 錯誤寫法
如果解構不成功,變量的值就等于`undefined`。
~~~
let [x, y, ...z] = ['a'];
console.log( x ) // "a"
console.log( y ) // undefined
console.log( z ) // []
~~~
以下兩種情況都屬于解構不成功,foo的值都會等于undefined。
另一種情況是不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組。這種情況下,解構依然可以成功。
~~~
let [foo] = [];
let [bar, foo] = [1];
~~~
以上兩種情況都屬于解構不成功,foo的值都會等于undefined。
~~~
let [x, y] = [1, 2, 3];
console.log( x ) // 1
console.log( y ) // 2
let [a, [b], d] = [1, [2, 3], 4];
console.log( a ) // 1
console.log( b ) // 2
console.log( d ) // 4
~~~
上面兩個例子,都屬于不完全解構,但是可以成功。
~~~
// 報錯
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
~~~
上面的語句都會報錯,因為等號右邊的值,要么轉為對象以后不具備 Iterator 接口(前五個表達式),要么本身就不具備 Iterator 接口(最后一個表達式)。
<br/>
>[success] ## 默認值
解構賦值允許指定默認值,可以賦值默認值的位置是等號的左面(let [a='3'] = [])
~~~
let [foo = true] = [];
console.log( foo ) // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
~~~
注意,ES6 內部使用嚴格相等運算符(===),判斷一個位置是否有值。所以,如果一個數組成員不嚴格等于undefined,默認值是不會生效的。
~~~
let [x = 1] = [undefined];
console.log( x ) // 1
let [x = 1] = [null];
console.log( x ) // null
~~~
~~~
function f() {
console.log('aaa');
}
let [x = f()] = [1];
~~~
上面代碼中,因為x能取到值,所以函數f根本不會執行。上面的代碼其實等價于下面的代碼。
~~~
let x;
if ([1][0] === undefined) {
x = f();
} else {
x = [1][0];
}
~~~
默認值可以引用解構賦值的其他變量,但該變量必須已經聲明。
~~~
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
~~~
上面最后一個表達式之所以會報錯,是因為x用到默認值y時,y還沒有聲明。
- Javascript基礎篇
- Array數組
- 數組插入值
- filter()
- forEach()
- push()
- pop()
- unshift()
- shift()
- valueOf()
- 面向對象思想
- Javascript 面向對象編程(一):封裝
- Javascript面向對象編程(二):構造函數的繼承
- Javascript面向對象編程(三):非構造函數的繼承
- 解構
- 數組的解構賦值
- 對象的解構賦值
- 函數參數解構
- 字符串的解構賦值
- 數值和布爾值的解構賦值
- 圓括號問題
- 字符串.
- split()
- charAt()
- charCodeAt()
- concat()
- indexOf()
- lastIndexOf()
- match()
- replace()
- includes()
- 初識遞歸
- 渲染ul-li樹形結構
- 異步函數解決方案
- 1. callback回調函數
- 2. ES6 - Promise
- JavaScript高級程序設計(書)
- 在html中使用JavaScript
- script標簽的位置
- 延遲腳本
- 異步腳本
- <noscript>元素
- 基本概念
- 嚴格模式
- 變量詳解
- 數據類型
- typeof操作符
- undefined類型
- Null類型
- Boolean類型
- Number類型
- 深入了解ES6(書)
- var 、let 、 const
- 字符串與正則表達式
- 字符串
- 正則表達式
- 函數
- 函數形參默認值
- 使用不具名參數
- 函數構造器的增強能力
- 擴展運算符
- name屬性
- 明確函數的多重用途
- 塊級函數
- 箭頭函數
- 尾調用優化
- 擴展的對象功能
- 對象類別
- 對象字面量語法的擴展
- ES6對象新增方法
- 重復的對象屬性
- 自有屬性的枚舉順序
- 更強大的原型
- 解構:更方便的數據訪問
- 為什么要用解構?
- 對象解構
- 數組解構
- 混合解構
- 參數解構
- Symbol與Symbol屬性
- 創建Symbol
- Symbol的使用方法
- Symbol全局私有屬性
- Symbol與類型強制轉換
- Symbol屬性檢索
- Symbol的一些構造方法
- Set集合與Map集合
- Set集合
- Weak Set集合(弱引用Set集合)
- Map集合
- JS標準內置對象
- Object 構造函數及屬性
- Object 構造方法
- Symbol 內建對象類的函數及屬性
- Set 構造函數及屬性
- Weak Set 構造函數及屬性
- JS雜項
- 類數組對象
- Class類的理解和使用