文章目录
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 }