es6解構(gòu)支持字符串。ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu);通過解構(gòu)賦值可以將屬性值從對象/數(shù)組中取出賦值給其他變量。字符串也可以解構(gòu)賦值,字符串會被轉(zhuǎn)換成了一個類似數(shù)組的對象;類似數(shù)組的對象都有一個length屬性,因此還可以對這個屬性解構(gòu)賦值。
前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點擊使用
本教程操作環(huán)境:windows10系統(tǒng)、ECMAScript 6版、Dell G3電腦。
es6的解構(gòu)是什么意思
destructuring:百度百科的意思是結(jié)構(gòu)分解,ES6 中允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)(Destructuring)。
解構(gòu)賦值語法是一種 Javascript 表達式,通過解構(gòu)賦值可以將屬性值從對象/數(shù)組中取出賦值給其他變量
ES6 允許按照一定模式,從數(shù)組和對象中提取值,對變量進行賦值,這被稱為解構(gòu)
開發(fā)中比較常見的有字符串解構(gòu)、對象解構(gòu)、 數(shù)組解構(gòu)、混合解構(gòu)。這是一種將數(shù)據(jù)結(jié)構(gòu)分解為更小的部分的過程,從而達到簡化提取信息的目的。
1. 基本數(shù)據(jù)類型解構(gòu)
1-1 字符串解構(gòu)賦值
字符串也可以解構(gòu)賦值,字符串會被轉(zhuǎn)換成了一個類似數(shù)組的對象
類似數(shù)組的對象都有一個length
屬性,因此還可以對這個屬性解構(gòu)賦值
// 會將字符串轉(zhuǎn)換成一個類數(shù)組對象 let [a, b, c, d ,e] = 'hello'; console.log(a, b, c, d ,e); // h e l l o // 類數(shù)組對象lenth 屬性解構(gòu) let {length : num} = 'hello'; console.log(num); // 5
1-2 數(shù)值、布爾值解構(gòu)賦值
解構(gòu)賦值時,如果等號右邊是數(shù)值和布爾值,則會先轉(zhuǎn)為對象
解構(gòu)賦值的規(guī)則是,只要等號右邊的值不是對象或數(shù)組,就先將其轉(zhuǎn)為對象
數(shù)值和布爾值的包裝對象都有 toString
屬性,變量都能取到值
let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true
由于 undefined
和 null
無法轉(zhuǎn)為對象,所以對它們進行解構(gòu)賦值,都會報錯
let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
2. 數(shù)組解構(gòu)
2-1 基本用法
- 數(shù)組可以變量聲明并賦值時解構(gòu),也可以在變量先聲明后賦值時解構(gòu)
// 數(shù)組可以在變量聲明并賦值時解構(gòu) let arr = ['jsx', 'ljj', 'zdj', 'ddc'] let [one, two, three, four] = arr; console.log(one, two, three, four); // jsx ljj zdj ddc // 也可以在變量先聲明后賦值解構(gòu) let name1, name2, name3, name4; [name1, name2, name3, name4] = ['jsx', 'ljj', 'zdj', 'ddc']; console.log(name1, name2, name3, name4); // jsx ljj zdj ddc
2-2 完全解構(gòu)
- 只要等號兩邊的模式相同,左邊的變量就會被賦予對應(yīng)的值
let [one, two, three] = ['html', 'css', 'js']; console.log(one, two, three); // html css js let [str1, [str2], str3] = ['jsx', ['ljj'], 'ddc'] console.log(str1, str2, str3); // jsx ljj ddc
- 數(shù)組中不想要的元素也可以使用逗號
,
來忽略
let [, , name] = ['haha', 'xixi', 'jsx']; console.log(name); // jsx let [, xixi , ] = ['haha', 'xixi', 'jsx']; console.log(xixi); // xixi
- 當解構(gòu)一個數(shù)組時,可以使用擴展語法
...
,將數(shù)組剩余部分賦值給一個變量
let [num, ...numN] = [1, 2, 3, 4]; console.log(num); // 1 console.log(numN); // [2, 3, 4]
- 交換變量值,在一個解構(gòu)表達式中可以交換兩個變量的值
let name1 = 'jsx'; let name2 = 'ljj'; let name3 = 'ddc'; [name1, name2, name3] = [name3, name1, name2]; console.log(name1, name2, name3); // ddc jsx ljj
- 等號右側(cè)可以是任何可迭代對象(具備
Iterator
接口對象或數(shù)組)
let [a, b, c] = 'jsx'; console.log(a, b, c); // j s x let [one1, two1, three1] = new Set([1, 2, 3]); console.log(one1, two1, three1); // 1 2 3
2-3 不完全解構(gòu)
- 當?shù)忍栕筮叺淖兞恐黄ヅ湟徊糠值牡忍栍疫叺臄?shù)組,右邊的數(shù)組多余元素會被忽略
let [one, two] = [1, 2, 3]; console.log(one, two); // 1 2 let [a, [b], c] = [1, [2, 3], 4] console.log(a, b, c); // 1 2 4
- 當?shù)忍栕筮叺淖兞繑?shù)量多于等號右邊的數(shù)組元素,解構(gòu)賦值左邊多余的變量則為
undefined
let [str1, str2] = ['jsx']; console.log(str1, str2); // jsx undefined
- 擴展語法
...
變量解構(gòu)時匹配不到元素值時返回[]
空數(shù)組
let [str3, ...str4] = ['jsx']; console.log(str3, str4); // jsx []
- 如果等號的右邊不是數(shù)組,也不是可迭代對象,那么解構(gòu)賦值將會報錯
let [foo1] = 1; let [foo2] = false; let [foo3] = NaN; let [foo4] = undefined; let [foo5] = null; let [foo6] = {}; console.log(foo1, foo2, foo3, foo4, foo5, foo6); // is not iterable
2-4 默認值
- 數(shù)組解構(gòu)時可以在表達式左邊的數(shù)組中為任意對象預(yù)設(shè)默認值
let [name1 = 'jsx', name2 = 'ljj'] = []; console.log(name1, name2); // jsx ljj
ES6
內(nèi)部使用嚴格相等運算符===
判斷一個位置是否有值,當一個數(shù)組缺少的值時,元素嚴格等于undefined
,默認值才會生效
let [num = 123] = [undefined]; console.log(num); // 123 // null !== undefined means let [num1 = 123] = [null]; // null嚴格相等undefined所有默認值無效 console.log(num1); // null
- 如果默認值是一個函數(shù)聲明,函數(shù)聲明是惰性求值的,只有在右邊沒有匹配值時才會執(zhí)行
function func() { return 123 } let [num2 = func()] = [undefined]; console.log(num2)
- 默認值可以引用解構(gòu)賦值的其他變量,但該變量必須已經(jīng)聲明
let [str1 = 'jsx', str2 = str1] = []; console.log(str1, str2); // jsx jsx // str4未聲明 let [str3 = str4, str4 = 'ljj'] = []; // Uncaught ReferenceError
3. 對象解構(gòu)
3-1 基本用法
- 基本語法
let {var1, var2} = {var1:…, var2:…}
- 對象解構(gòu)賦值與先聲明后獨立進行解構(gòu)賦值
let { name, age } = { name: 'jsx', age: 22 }; console.log(name, age); // jsx 22 // 先聲明后獨立解構(gòu)賦值 let a, b; // 賦值語句需要通過()包圍 因為{}是一個塊級而不是字面量 ({a, b} = {a: 1, b: 2}); console.log(a, b); // 1 2
3-2 屬性變量同名
- 對象的屬性沒有次序,左邊的變量必須與對象屬性同名,才能取到正確的值
let {name, age} = {name: 'jsx', age: 22}; console.log(name, age); // jsx 22
- 當變量沒有對應(yīng)的同名對象屬性時,會導(dǎo)致1取不到值返回
undefined
// 如果解構(gòu)失敗,變量的值等于undefined let {a, b} = {a: 'jsx', c: 'ljj'}; console.log(a, b); // jsx undefined
3-3 屬性變量不同名
- 當變量名與對象屬性名不一致時,可以使用冒號
:
來設(shè)置,將對象屬性值賦值給:
冒號后的變量
let {user: name, age: num} = {user: 'jsx', age: 22} console.log(name, num); // jsx 22
foo:baz
此時冒號前面foo
則是匹配模式匹配對象屬性,baz
則是匹配屬性的值
let {foo:baz} = {name: 'jsx'}; console.log(foo); // ncaught ReferenceErro console.log(baz); // undefined
- 先找到同名屬性,然后再賦給對應(yīng)的變量,真正被賦值的是后者,而不是前者
let {name: str, age: num1} = {user: 'jsx', age: 22}; console.log(str, num1); // undefined 22
- 數(shù)組對象嵌套解構(gòu)賦值
let obj = { lesson: ['html', { class: 'css' }] } let { lesson: [x, { class: y }] } = obj; // console.log(x, y); // html css let { lesson } = obj; console.log(lesson); // ['html', {…}] let obj1 = {}; let arr1 = []; ({ foo: obj1.prop, bar: arr1[0] } = { foo: 123, bar: true }); console.log(obj1) // {prop:123} console.log(arr1) // [true]
- 對象的解構(gòu)賦值可以取到對象繼承的屬性
let obj2 = {}; let obj3 = { user: 'ljj' }; Object.setPrototypeOf(obj2, obj3); let { user } = obj2; console.log(user); // ljj
- 可以使用擴展語法
...
將對象剩余的屬性與值賦值給一個變量
let options = { title: "Menu", height: 200, width: 100 }; // title = 名為 title 的屬性 // rest = 存有剩余屬性的對象 let { title, ...rest } = options; // 現(xiàn)在 title="Menu", rest={height: 200, width: 100} console.log(rest.height); // 200 console.log(rest.width); // 100
3-4 默認值
- 對象的解構(gòu)也可以指定默認值,默認值生效的條件是對象的屬性值嚴格等于
undefined
let {name = 'jsx'} = {}; console.log(name); // jsx let {name1 = 'jsx'} = {name1: 'ljj'}; // 默認值失效 console.log(name1); // ljj // 當對象屬性值為undefined時有效 let {name2 = 'jsx'} = {name2: undefined}; console.log(name2); // jsx let {x: y = 3} = {x: 5}; console.log(y); // 5 let {x1 = 3} = {x1: null}; console.log(x1); // null
- 當指定的對象屬性不存在時,直接在變量后添加默認值
- 當指定的對象屬性存在,而屬性值不存在或者為
undefined
時,先匹配屬性再在變量值后添加一個等號=
和相應(yīng)的默認值即可
let {user: xm = 'jsx'} = {}; console.log(xm); // jsx
4. 嵌套解構(gòu)
如果一個對象或數(shù)組嵌套了其他的對象和數(shù)組,我們可以在等號左側(cè)使用更復(fù)雜的模式(pattern)來提取更深層的數(shù)據(jù)
// 數(shù)組嵌套 let [name, [name1, [name2]]] = ['jsx', ['ljj', ['ddc']]]; console.log(name, name1, name2); // jsx ljj ddc // 對象解構(gòu) let obj = { title: '對象解構(gòu)', info: { target: '對象', difficulty: { level: 1 } } } let { title, info, info: { target, difficulty, difficulty: { level } } } = obj; console.log(title, info, target, difficulty, level); // 對象解構(gòu) // {target: '對象', difficulty: {…}} // 對象 // {level: 1} // 1 // 對象數(shù)組嵌套 let objArr = { message: '對象數(shù)組嵌套', lesson: ['html', 'css', 'js'], news: { main: '新消息' } } let { message, lesson, lesson: [item1, item2, item3], news, news: { main } } = objArr; console.log(message, lesson, item1, item2, item3, news, main) // 對象數(shù)組嵌套 // ['html', 'css', 'js'] // html css js // {main: '新消息'} // 新消息
5. 函數(shù)參數(shù)解構(gòu)
一個函數(shù)可以有很多參數(shù),其中大部分的參數(shù)都是可選的
- 把所有參數(shù)當作一個數(shù)組來傳遞,然后函數(shù)馬上把這個數(shù)組解構(gòu)成多個變量
function arrFn([name, age]) { console.log(name, age) } arrFn(['jsx', 22]); // jsx 22
- 把所有參數(shù)當作一個對象來傳遞,然后函數(shù)馬上把這個對象解構(gòu)成多個變量
let obj = { title: "My menu", items: ["Item1", "Item2"] } function objFn({ title, items: [item1, item2] }) { console.log(title); // My menu console.log(item1, item2); // Item1 Item2 } objFn(obj);
- 可以使用帶有嵌套對象和冒號映射的更加復(fù)雜的解構(gòu)
// 語法 function({ incomingProperty: varName = defaultValue ... }) let obj1 = { message: '嵌套帶冒號', info: { name: 'jsx', lesson: ['html', 'css'], grilfriend: { xm: 'ljj' } } } function complexFn({ message, info: { name, lesson: [list1, list2], grilfriend: { xm } } }) { console.log(message); // 嵌套帶冒號 console.log(list1, list2); // html css console.log(xm); // ljj } complexFn(obj1);
- 可以通過指定空對象
{}
為整個參數(shù)對象設(shè)置默認值
function nullFn({ info = 'jsx', width = 100, height = 200 } = {}) { console.log(info); // jsx console.log(width); // 100 console.log(height); // 200 } nullFn();
6. 圓括號問題
不可以使用圓括號的情況:
-
變量聲明語句,不得使用圓括號
-
函數(shù)參數(shù)也屬于變量聲明,因此不能帶有圓括號
-
賦值語句的模式,將整個模式放在圓括號之中,導(dǎo)致報錯
// 聲明語句時不能使用圓括號包裹變量 let [(num)] = [1]; console.log(a); // Uncaught SyntaxError let {(name: str)} = {name: 'jsx'}; console.log(str); // Uncaught SyntaxError // 函數(shù)參數(shù)內(nèi)也不可以 function fn([(a)]) { console.log(a); } fn(1); // 賦值語句內(nèi)不可使用圓括號包裹 let a, b; ([a, b]) = [1, 2]; console.log(a, b) // Uncaught SyntaxError
可以使用圓括號的情況:
- 賦值語句的非模式部分,可以使用圓括號
let num; [(num)] = [123]; console.log(num); // 123 let str; ({name: str} = {name: 'jsx'}); console.log(str); // jsx
7. 解構(gòu)賦值使用場景
- 交換變量的值
let name1 = 'jsx'; let name2 = 'ljj'; [name1, name2] = [name2, name1]; console.log(name1, name2); // ljj, jsx
- 從函數(shù)返回多個值
function returnFn() { return { name: 'jsx', age: 22 } } let { name, age } = returnFn(); console.log(name, age); // jsx 22
- 函數(shù)參數(shù)的定義
function argumentFn([list1, list2]) { console.log(list1); // jsx console.log(list2); // ljj } argumentFn(['jsx', 'ljj']) function argumentFn1({obj}) { console.log(obj); // jsx } argumentFn1({obj: 'jsx'})
- 提取
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' (2) [867, 5309]
- 函數(shù)參數(shù)的默認值
function func({ title = '默認值' } = {}) { console.log(title) } func(); // 默認值
- 遍歷
Map
結(jié)構(gòu)
const 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 }
- 與
.entries()
方法進行循環(huán)操作
let user = { name: "John", age: 30 }; for (let [key, value] of Object.entries(user)) { console.log(`${key}: ${value}`); // name: John // age: 30 }
- 輸入模塊的指定方法
<script type="module"> import {sayHi, sayHello} from './index.js'; sayHi(); // say hi sayHello(); // say hello </script>
// index.js export function sayHi() { console.log('say hi') } export function sayHello() { console.log('say hello') }
【