工作中经常会有需要将两个对象合并成一个对象,在 jQuery 时代我们可以用它的 extend
方法来实现,但是从 ES6 开始,我们就可以用原生对象方法 Object.assign()
来实现了
Object.assign() 的基本使用
通过 Object.assign()
,可以将一个至多个源对象上的可枚举属性(enumerable)拷贝到目标对象上,并将目标对象返回
const a = {a: 1}
const b = {b: 2}
const c = {c: 3}
Object.assign({}, a, b, c)
// {a: 1, b: 2, c: 3}
Object.assign()
的第一个参数是目标对象,之后可以有多个参数作为需要拷贝的源对象,如果目标对象与源对象中存在同名的属性,后面的都将覆盖前面的属性
const d1 = {d: 5}
const d2 = {d: 6}
const d3 = {d: 7}
Object.assign({d: 4}, d1, d2, d3)
// {d: 7}
需要注意的是,Object.assign()
方法执行的是浅拷贝,也就是说如果源对象的某个属性是对象,那么拷贝进目标对象的将是这个对象属性的引用
const e = {e: 8}
const f = {f: e} // f.f 是一个对象
const g = Object.assign({}, f) // {f: e}
f === g // false f和g是两个不同的对象
f.f === g.f // true 由于浅拷贝,f.f和g.f指向同一块内存,也就是e所占用的内存
关于对象的深浅拷贝,不了解的小伙伴可以看之前的一篇文章:
因此,一旦遇到同名属性,Object.assign()
将直接替换
const h1 = {h: {i: 9, j: 10}}
const h2 = {h: {k: 11}}
Object.assign(h1, h2)
// {h: {k: 11}}
上面这个例子中,并没有像我们预想的一样返回 {h: {i: 9, j: 10, k: 11}}
,而是直接将 h2
的 h
属性替换了 h1
的 h
属性
对于第一个参数不是对象的情况:
如果第一个参数不是对象,Object.assign()
会将它转为对象
typeof Object.assign(2)
// Object
而 undefined 和 null 无法转成对象,因此它们作为第一个参数会报错
对于其他参数不是对象的情况:
Object.assign()
依然会试图将其转为对象,但如果不能转换,则会直接跳过该参数,因此传入 undefined 或 null 不会报错
对于字符串、数值、布尔值这些类型来说,虽然能被转为对象,但是由于数值、布尔值等类型转成的对象上不具有可枚举的属性,因此也会被直接忽略。而字符串转成的对象上具有可枚举属性,因此会被拷贝到目标对象上
Object.assign({}, 'abc', 1, true)
// {0: 'a', 1: 'b', 2: 'c'}
Object.assign() 的限制:
首先限制之一是上面说过的只拷贝可枚举属性,另一个就是它只拷贝对象本身具有的属性,对于继承来的属性不会被拷贝
Object.assign() 的常见用途
- 为对象添加属性/指定默认属性
- 合并多个对象
- 克隆对象
Object.assign({}, aimObj)
// aimObj 为需要被克隆的对象,返回克隆对象
- 为对象添加方法
Object.assign(AClass.prototype, {
func1 () {...},
func2 () {...}
})
扫码关注前端周记公众号
网友评论