ES6 对象新增的一些方法
Object.is()
ES5 比较两个值是否相等,只有两个运算符:相等运算符(==
)和严格相等运算符(===
)。它们都有缺点,前者会自动转换数据类型,后者的NaN
不等于自身,以及+0
等于-0
。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
console.log(+0 === -0) // true
console.log(NaN === NaN) // false
Object.is() 方法与 ===
运算符功能基本一致,同时修正了上述的两个问题:
console.log(Object.is(+0, -0)) // false
console.log(Object.is(NaN, NaN)) // true
Object.assign()
基础使用
Object.assign()
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
const target = {}
const obj1 = { a: 1 }
const obj2 = { b: 2 }
const obj3 = { c: 3 }
Object.assign(target, obj1, obj2, obj3)
console.log(target) // { a: 1, b: 2, c: 3 }
注意:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const target = { a: 1, b: 2 }
const obj1 = { a: 10 }
const obj2 = { b: 20 }
Object.assign(target, obj1, obj2)
console.log(target) // { a: 10, b: 20 }
注意:Object.assign() 方法返回值就是 target
const target = { a: 1, b: 2 }
const obj1 = { a: 10 }
const obj2 = { b: 20 }
const t2 = Object.assign(target, obj1, obj2)
console.log(Object.is(t2, target)) // true
注意事项
浅拷贝
Object.assign()
方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = { a: { b: 1 } }
const obj2 = Object.assign({}, obj1)
obj2.a.b = 10
console.log(obj1) // { a: { b: 10 } }
console.log(obj2) // { a: { b: 10 } }
同名属性替换
对于这种嵌套的对象,一旦遇到同名属性,Object.assign()
的处理方法是替换,而不是添加。
const target = { a: { b: 1 } }
const source = { a: { c: 1 } }
console.log(Object.assign(target, source)) // { a: { c: 1 } }
数组的处理
Object.assign()
可以用来处理数组,但是会把数组视为对象。
console.log(Object.assign({}, [1, 2, 3])) // { '0': 1, '1': 2, '2': 3 }
// 数组处理
console.log(Object.assign([1, 2, 3], [4, 5])) // [ 4, 5, 3 ]
Object.keys()、Object.values()、Object.entries()
ES5 引入了Object.keys
方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
Object.values
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
Object.entries()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
const person = { name: '张三', gender: '男', age: 22 }
console.log(Object.keys(person)) // [ 'name', 'gender', 'age' ]
console.log(Object.values(person)) // [ '张三', '男', 22 ]
console.log(Object.entries(person)) // [ [ 'name', '张三' ], [ 'gender', '男' ], [ 'age', 22 ] ]
Object.fromEntries()
Object.fromEntries()
方法是Object.entries()
的逆操作,用于将一个键值对数组转为对象。
let keyValues = [ [ 'name', '张三' ], [ 'gender', '男' ], [ 'age', 22 ] ]
console.log(Object.fromEntries(keyValues)) // { name: '张三', gender: '男', age: 22 }
Object.getOwnPropertyDescriptors()
ES5 的Object.getOwnPropertyDescriptor()
方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()
方法,返回指定对象所有自身属性(非继承属性)的描述对象。
const obj = {
name: '张三',
sayHello() {
console.log('hello')
}
}
console.log(Object.getOwnPropertyDescriptors(obj))
// {
// name: { value: '张三', writable: true, enumerable: true, configurable: true },
// sayHello: {
// value: [Function: sayHello],
// writable: true,
// enumerable: true,
// configurable: true
// }
// }
Object.setPrototypeOf()、Object.getPrototypeOf()
Object.setPrototypeOf
方法的作用与__proto__
相同,用来设置一个对象的原型对象(prototype),返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
该方法与Object.setPrototypeOf
方法配套,用于读取一个对象的原型对象。