ES6 新特性: 解构赋值

文章目录

1.解构赋值

对象中有很多数据,现在我们需要从对象中取出某些数据赋值给指定变量

javascript 复制代码
const user = { name: "辰风沐阳", age: 20, gender: '男', height: 180, weight: 130 }

在 es6 之前,获取对象中的某些值,需要通过 对象.属性名 获取

javascript 复制代码
let name = user.name
let gender = user.gender
let weight = user.weight

如果需要获取的属性很多时,要写大量 . 来获取,这种方式显然不够简洁美观,我们需要一种更优雅的写法

es6 引入了很多新特性,其中之一就是解构。直接从对象或数组中批量提取值,并将值赋给变量,从而使代码更加简洁易读

javascript 复制代码
let { name, gender, weight } = user
2.对象解构

最基础的用法:同名变量解构赋值,只提取需要的值,并且赋给变量

javascript 复制代码
const user = { name: "liang", age: 20, height: 180 }
let { name, age } = user
console.log({ name, age }); // { name: 'liang', age: 20 }

也支持给解构出来的属性指定新的变量名称,使用 : 即可指定新的变量名

javascript 复制代码
const user = { name: "liang", age: 20, height: 180 }
let { name: userName } = user
console.log(userName); // liang

如果解构的变量,在对象中没有同名属性,那么该变量会被赋值为 undefined,可以使用 = 指定解构的默认值

javascript 复制代码
const user = { name: "liang" }
let { age } = user
console.log(age); // undefined

const user = { name: "liang" }
let { age = 20 } = user // 使用 "=" 可以指定解构的默认值
console.log(age); // 20

对于多层对象的解构,可以深入到嵌套的对象结构中去提取想要的数据,同样支持指定新的变量名、解构默认值

javascript 复制代码
const user = {
    name: "liang",
    info: { weight: 70, height: 180 }
}
let { info: { weight, height: length } } = user
console.log({ weight, length }); // { weight: 70, length: 180 }
3.数组解构

数组解构的语法和对象解构的语法非常相似,只是将对象字面量替换为了数组字面量

  • 对象解构:作用在对象的具名属性上,解构时关注属性名称
  • 数组解构:作用在数组的元素位置上,解构时关注元素位置

数组解构基础用法:按照元素的位置,依次赋值给指定变量

javascript 复制代码
const [a, b] = ['red', 'green', 'blue']
console.log(a); // red
console.log(b); // green

如果不想解构某些值,可以使用逗号直接略过,数组解构也可以使用 = 指定解构的默认值

javascript 复制代码
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

剩余项解构:先解构部分,然后将剩余项全部解构到一个变量。使用 ... 将剩余项目赋值给指定的一个变量

javascript 复制代码
const [a, ...b] = ['red', 'green', 'blue']
console.log(a); // red
console.log(b); // ['green', 'blue']
4.参数解构

参数解构是指在函数定义时,直接从传入的参数中解构出所需要的属性,使代码更简洁、更具可读性

对象参数解构:当函数接收一个对象作为参数时,可以在函数参数中使用对象解构,提取所需属性

javascript 复制代码
// 只需要用到 id 和 age,那么可以只将它们解构出来,同样也支持设置默认值
function getInfo({ id, age = 20 }) {
    console.log({ id, age }); // { id: 10, age: 20 }
}
// 对象中传递多个值
getInfo({ id: 10, name: 'liang', height: 180 });

实际开发中,前端有些下拉框数据需要从后端接口获取,但是接口返回的列表数据字段有很多,并且字段名和我们组件需要的字段名不一致。那么我们可以将接口返回的数据重新构建为我们需要的结构,此时就会用到 Array.map() 方法

javascript 复制代码
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 }))

对象参数解构,在实际开发中是非常多的,下面是在 Vuex 中使用对象参数解构的场景

javascript 复制代码
const store = new Vuex.Store({
    actions: {
        update(context) {
            // 通过打印可以发现 context 对象上有 state getters commit dispatch 等属性
            // 但是,我们可能只使用到其中某些属性,比如:只需要用到 context.commit 属性
            console.log(context);
        },
        // 对象参数解构用法示例
        getUser({ commit }) {
            return new Promise(resolve => {
                uni.$u.http.get('/auth/info').then(res => {
                    if (res.code == 200) {
                        commit('SET_USERINFO', res.data)
                    }
                    resolve()
                })
            })
        },
    }
})

还可以用于封装功能函数,配置项处理等场景,让函数更灵活,易于扩展

javascript 复制代码
function request({ url, method = 'GET', params = {}, data = {} }) {
    // 执行请求逻辑
}

数组参数解构:当函数接收一个数组作为参数时,也可以在函数参数中使用数组解构

javascript 复制代码
function sum([a, b]) {
    return a + b
}
console.log(sum([1, 2]));
5.可迭代对象

可迭代协议

通常情况下,我们都是对数组进行数组解构,对象进行对象解构。但是,对象能进行数组解构吗 ?

javascript 复制代码
// 将一个对象进行数组解构,此时会报错
let [a, b] = { a: 3, b: 4 }

// 报错信息如下所示,意思是 intermediate value 不是一个可迭代的东西
// Uncaught TypeError: {(intermediate value)(intermediate value)} is not iterable

那么,如何能将对象能进行数组解构,使上面代码成立呢 ?这是也是一个常见的面试题

javascript 复制代码
// 面试题:让下面的代码成立
let [a, b] = { a: 3, b: 4 }

首先,我们要明白一个概念,什么是可迭代对象 ?

可迭代对象:是指满足可迭代协议的对象,可迭代协议是对象中函数名为 Symbol.iterator 的成员

javascript 复制代码
let data = {
    a: 3,
    b: 4,
    // 可迭代协议
    [Symbol.iterator]() {
        return '迭代器'
    }
}
数组解构的本质

所以解构时右边只要放一个可迭代的对象就可以了,数组解构时右边通常放的是一个数组,说明数组就是可迭代对象

javascript 复制代码
const arr = [3, 4]

// 可以看到数组确实有 Symbol.iterator 属性,并且它是一个函数
console.log(arr[Symbol.iterator]); // ƒ values() { [native code] }

// 可迭代协议函数的返回值是一个迭代器
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}

所以,我们可以得到结论:

javascript 复制代码
const arr = [3, 4]

// 以下代码
// let [a, b] = arr

// 等同于
const iter = arr[Symbol.iterator]()
let a = iter.next().value
let b = iter.next().value

以下为面试题答案,就是给对象增加可迭代协议,使其支持数组解构

javascript 复制代码
Object.prototype[Symbol.iterator] = function () {
    // this 为当前对象数据,如:{ 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 }
相关推荐
猫头鹰源码(同名B站)2 小时前
基于django+vue的时尚穿搭社区(商城)(前后端分离)
前端·javascript·vue.js·后端·python·django
weixin_427771612 小时前
npm 绕过2FA验证
前端·npm·node.js
零基础的修炼2 小时前
算法---常见位运算总结
java·开发语言·前端
wgslucky2 小时前
sm2 js加密,java服务器端解密
java·开发语言·javascript
wuhen_n2 小时前
@types 包的工作原理与最佳实践
前端·javascript·typescript
我是伪码农2 小时前
Vue 1.27
前端·javascript·vue.js
秋名山大前端2 小时前
前端大规模 3D 轨迹数据可视化系统的性能优化实践
前端·3d·性能优化
H7998742422 小时前
2026动态捕捉推荐:8款专业产品全方位测评
大数据·前端·人工智能
ct9782 小时前
Cesium 矩阵系统详解
前端·线性代数·矩阵·gis·webgl