1.解構賦值
對象中有很多數(shù)據(jù),現(xiàn)在我們需要從對象中取出某些數(shù)據(jù)賦值給指定變量
const user = { name: "辰風沐陽", age: 20, gender: '男', height: 180, weight: 130 }
在 es6 之前,獲取對象中的某些值,需要通過 對象.屬性名 獲取
let name = user.name
let gender = user.gender
let weight = user.weight
如果需要獲取的屬性很多時,要寫大量 . 來獲取,這種方式顯然不夠簡潔美觀,我們需要一種更優(yōu)雅的寫法
es6 引入了很多新特性,其中之一就是解構。直接從對象或數(shù)組中批量提取值,并將值賦給變量,從而使代碼更加簡潔易讀
let { name, gender, weight } = user
2.對象解構
最基礎的用法:同名變量解構賦值,只提取需要的值,并且賦給變量
const user = { name: "liang", age: 20, height: 180 }
let { name, age } = user
console.log({ name, age }); // { name: 'liang', age: 20 }
也支持給解構出來的屬性指定新的變量名稱,使用 : 即可指定新的變量名
const user = { name: "liang", age: 20, height: 180 }
let { name: userName } = user
console.log(userName); // liang
如果解構的變量,在對象中沒有同名屬性,那么該變量會被賦值為 undefined,可以使用 = 指定解構的默認值
const user = { name: "liang" }
let { age } = user
console.log(age); // undefined
const user = { name: "liang" }
let { age = 20 } = user // 使用 “=” 可以指定解構的默認值
console.log(age); // 20
對于多層對象的解構,可以深入到嵌套的對象結構中去提取想要的數(shù)據(jù),同樣支持指定新的變量名、解構默認值
const user = {
name: "liang",
info: { weight: 70, height: 180 }
}
let { info: { weight, height: length } } = user
console.log({ weight, length }); // { weight: 70, length: 180 }
3.數(shù)組解構
數(shù)組解構的語法和對象解構的語法非常相似,只是將對象字面量替換為了數(shù)組字面量
- 對象解構:作用在對象的具名屬性上,解構時關注屬性名稱
- 數(shù)組解構:作用在數(shù)組的元素位置上,解構時關注元素位置
數(shù)組解構基礎用法:按照元素的位置,依次賦值給指定變量
const [a, b] = ['red', 'green', 'blue']
console.log(a); // red
console.log(b); // green
如果不想解構某些值,可以使用逗號直接略過,數(shù)組解構也可以使用 = 指定解構的默認值
const [a, , b] = ['red', 'green', 'blue']
console.log(a); // red
console.log(b); // blue
const [, , c] = ['red', 'green', 'blue']
console.log(c); // blue
const [, d = 'purple'] = ['red']
console.log(d); // purple
剩余項解構:先解構部分,然后將剩余項全部解構到一個變量。使用 ... 將剩余項目賦值給指定的一個變量
const [a, ...b] = ['red', 'green', 'blue']
console.log(a); // red
console.log(b); // ['green', 'blue']
4.參數(shù)解構
參數(shù)解構是指在函數(shù)定義時,直接從傳入的參數(shù)中解構出所需要的屬性,使代碼更簡潔、更具可讀性
對象參數(shù)解構:當函數(shù)接收一個對象作為參數(shù)時,可以在函數(shù)參數(shù)中使用對象解構,提取所需屬性
// 只需要用到 id 和 age,那么可以只將它們解構出來,同樣也支持設置默認值
function getInfo({ id, age = 20 }) {
console.log({ id, age }); // { id: 10, age: 20 }
}
// 對象中傳遞多個值
getInfo({ id: 10, name: 'liang', height: 180 });
實際開發(fā)中,前端有些下拉框數(shù)據(jù)需要從后端接口獲取,但是接口返回的列表數(shù)據(jù)字段有很多,并且字段名和我們組件需要的字段名不一致。那么我們可以將接口返回的數(shù)據(jù)重新構建為我們需要的結構,此時就會用到 Array.map() 方法
const lists = [
{ id: 1, name: 'html', score: 70, create_time: 1769390831 },
{ id: 2, name: 'css', score: 85, create_time: 1769390845 },
{ id: 3, name: 'javascript', score: 100, create_time: 1769390849 },
]
// 普通寫法
const ids1 = lists.map(item => ({ value: item.id, label: item.name }))
// 解構寫法
const ids2 = lists.map(({ id: value, name: label }) => ({ value, label }))
對象參數(shù)解構,在實際開發(fā)中是非常多的,下面是在 Vuex 中使用對象參數(shù)解構的場景
const store = new Vuex.Store({
actions: {
update(context) {
// 通過打印可以發(fā)現(xiàn) context 對象上有 state getters commit dispatch 等屬性
// 但是,我們可能只使用到其中某些屬性,比如:只需要用到 context.commit 屬性
console.log(context);
},
// 對象參數(shù)解構用法示例
getUser({ commit }) {
return new Promise(resolve => {
uni.$u.http.get('/auth/info').then(res => {
if (res.code == 200) {
commit('SET_USERINFO', res.data)
}
resolve()
})
})
},
}
})
還可以用于封裝功能函數(shù),配置項處理等場景,讓函數(shù)更靈活,易于擴展
function request({ url, method = 'GET', params = {}, data = {} }) {
// 執(zhí)行請求邏輯
}
數(shù)組參數(shù)解構:當函數(shù)接收一個數(shù)組作為參數(shù)時,也可以在函數(shù)參數(shù)中使用數(shù)組解構
function sum([a, b]) {
return a + b
}
console.log(sum([1, 2]));
5.可迭代對象
可迭代協(xié)議
通常情況下,我們都是對數(shù)組進行數(shù)組解構,對象進行對象解構。但是,對象能進行數(shù)組解構嗎 ?
// 將一個對象進行數(shù)組解構,此時會報錯
let [a, b] = { a: 3, b: 4 }
// 報錯信息如下所示,意思是 intermediate value 不是一個可迭代的東西
// Uncaught TypeError: {(intermediate value)(intermediate value)} is not iterable
那么,如何能將對象能進行數(shù)組解構,使上面代碼成立呢 ?這是也是一個常見的面試題
// 面試題:讓下面的代碼成立
let [a, b] = { a: 3, b: 4 }
首先,我們要明白一個概念,什么是可迭代對象 ?
可迭代對象:是指滿足可迭代協(xié)議的對象,可迭代協(xié)議是對象中函數(shù)名為 Symbol.iterator 的成員
let data = {
a: 3,
b: 4,
// 可迭代協(xié)議
[Symbol.iterator]() {
return '迭代器'
}
}
數(shù)組解構的本質(zhì)
所以解構時右邊只要放一個可迭代的對象就可以了,數(shù)組解構時右邊通常放的是一個數(shù)組,說明數(shù)組就是可迭代對象
const arr = [3, 4]
// 可以看到數(shù)組確實有 Symbol.iterator 屬性,并且它是一個函數(shù)
console.log(arr[Symbol.iterator]); // ? values() { [native code] }
// 可迭代協(xié)議函數(shù)的返回值是一個迭代器
const iter = arr[Symbol.iterator]()
console.log(iter); // 返回一個對象
// next() 表示得到下一項
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: 4, done: false}
所以,我們可以得到結論:
const arr = [3, 4]
// 以下代碼
// let [a, b] = arr
// 等同于
const iter = arr[Symbol.iterator]()
let a = iter.next().value
let b = iter.next().value
以下為面試題答案,就是給對象增加可迭代協(xié)議,使其支持數(shù)組解構
Object.prototype[Symbol.iterator] = function () {
// this 為當前對象數(shù)據(jù),如:{ a: 3, b: 4 }
return Object.values(this)[Symbol.iterator]()
}
// 簡化版:使用 ES6 的生成器(可以將上面代碼改造成以下生成器寫法)
// Object.prototype[Symbol.iterator] = function* () {
// yield* Object.values(this)
// }
// 面試題:讓下面的代碼成立
let [a, b] = { a: 3, b: 4 }