ES6 新特性: 解構賦值

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 }
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容