「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。
一、Object.values()
在之前我们要获取一个对象的每一个value值,需要进行如下处理:
let obj = {
name: 'zhangsan',
age: 18,
sex: 'male'
}
let res = Object.keys(obj).map(key => obj[key])
console.log(res) //['zhangsan', 18, 'male']
Object.values()的出现可以让我们更直接的获取value。他返回一个包含对象自身的所有可枚举属性值得数组。
let obj = {
name: 'zhangsan',
age: 18,
sex: 'male'
}
console.log(Object.values(obj)) //['zhangsan', 18, 'male']
我们肯定了解过for...in,我们是不是也可以用for...in处理上边的代码呢?不妨试一试,
let obj = {
name: 'zhangsan',
age: 18,
sex: 'male'
}
for(let prop in obj) {
console.log(obj[prop]); //'zhangsan', 18, 'male'
}
那么它与Object.values()有什么区别呢?
for...in以任意顺序遍历一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性 Object.values()只能遍历对象自身的可枚举属性值。
二、Object.entries()
Object.entries()返回给定对象自身的可枚举属性键值对数组,简单的说是一个二维数组。
let obj = {
name: 'zhangsan',
age: 18,
sex: 'male'
}
console.log(Object.entries(obj));
当参数是一个数组时,他的第一个值是下标
let arr = ['a','b','c']
console.log(Object.entries(arr));
三、Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors()用于获取对象自身属性描述符。
let obj = {name: '张三'}
console.log(Object.getOwnPropertyDescriptors(obj));
我们可以看到name属性下有四个值,这就是描述obj对象下name属性的描述符。
- value的值就是name对应的值
- configurable 描述的是该属性可不可以被delete删除 是个boolean类型
- enumerable 描述的是该属性可不可以被for...in遍历 是个boolean类型
- writable 描述的事该属性可不可以被修改 是个boolean类型
同样,我们也可以通过defineProperty来定义一个对象的属性的这些描述符
let obj = {name: '张三'}
Reflect.defineProperty(obj, 'name', {
value: '李四',
writable: false,
enumerable: false,
configurable: false
})
我们可以看到,Object.getOwnPropertyDescriptors()后面有一个s,我们也可以去掉这个s,当s去掉后,我们可以传第二个参数,第二个参数就是该对象下的某个属性。意思就是说,我们可以指定查看对象下某个属性的描述符
let obj = {name: '张三'}
console.log(Object.getOwnPropertyDescriptor(obj,'name'))
//{value: '张三', writable: true, enumerable: true, configurable: true}
四、ES9中的对象扩展
在ES9中,新增了对象的扩展运算,在之前,我们学过数组的扩展运算符,比如合并两个数组,我们就可以用数组的扩展运算符实现,代码如下:
let arr1 = [1,2,3]
let arr2 = [4,5,6]
let arr3 = [...arr1,...arr2]
console.log(arr3) //[1, 2, 3, 4, 5, 6]
其实对象也有扩展运算符,如下,我们可以克隆一个对象。
let obj1 = {
name: {
firstName: '三'
}
}
let obj2 = {...obj1}
console.log(obj2)
可以看到这是完全可以的,但是上边的代码是个浅拷贝,这是一个要注意的问题。
let obj1 = {
name: {
firstName: '三'
}
}
let obj2 = {...obj1}
obj1.name.firstName = '四'
console.log(obj2)
可以看到,obj2的值也变了,所以是个浅拷贝
- 同时,我们也可以合并两个对象,当对象中的属性重复时,后边的对象属性会覆盖前面对象的属性
let obj1 = {
name: '张三',
age: 18
}
let obj2 = {
name: '李四',
sex: 'male'
}
let obj3 = {...obj1, ...obj2}
console.log(obj3) //{name: '李四', age: 18, sex: 'male'}
同时,对象也可以用作剩余处理,例如下面的这段代码:
let obj = {
name: 'zhangsan',
age: 18,
school: '家里蹲',
sex: 'male'
}
let {name,age,...rest} = obj
console.log(name) //zhangsan
console.log(age) //18
console.log(rest) //{school: '家里蹲', sex: 'male'}
但是需要注意的是,...rest只能放在最后的位置,否则会报错
let obj = {
name: 'zhangsan',
age: 18,
school: '家里蹲',
sex: 'male'
}
let {name, ...rest, age} = obj
五、Promise.prototype.finally()
之前在学习Promise时,我们知道有then和catch方法,分别表示成功和失败的处理,而finally表示不管成功失败都要进行的回调函数。
new Promise((resolve,reject) => {
setTimeout(() => {
// resolve('success')
reject('fail')
},1000)
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
}).finally(fin => {
console.log('finally');
})
Promise.prototype.finally()的应用场景:
- ajax发送请求时,在等待接口响应11前的loading动画,无论成功还是失败都要关闭loading,如果没有finally,我们需要在then和catch中都写一遍关闭代码。有了finally,我们只需要写在finally中就可以了。