Object.assign()
介绍
该方法是ES6新增的接口,可以接收多个参数:第一个参数为目标对象,后边的参数为源对象;其作用是用来合并多个js对象:将多个源对象合并到目标对象上,如果出现同名的属性(方法)后合并的会覆盖掉之前合并的同名属性(方法)。也就是后边的优先级更高一点。assign不会合并不可枚举的属性
demo
let target = {
a: 1 };
let source1 = {
b: 2 };
let source2 = {
c: 3 };
let source3 = {
b: 4 };
console.log(Object.assign(target, source1, source2, source3));
// { a: 1, b: 4, c: 3 }
问题
问题1:参数类型问题
Object.assign()设计的主要目的是用来合并对象,所以理论上它接收到的参数是对象类型;如果参数不是对象类型则先转换成对象类型然后进行合并。
注意
- target 如果不是对象,则转换成对象;如果不能转换,就报错
- source 如果不是对象,则转换成对象;如果不能转换,则忽略
- null、undefined不能转换成对象类型
let target = {
};
let source1 = 'abc';
let source2 = null;
let source3 = {
"2": 4 };
console.log(Object.assign(target, source1, source2, source3));
// { '0': 'a', '1': 'b', '2': 4 }
问题2:拷贝属性限制
Object.assign拷贝的属性是有限制的,只会拷贝对象本身的属性(不会拷贝继承属性),也不会拷贝不可枚举的属性。但是属性名为Symbol值的属性,是可以被Object.assign拷贝的。
问题3:拷贝是深拷贝?浅拷贝?
Object.assign进行的拷贝是浅拷贝。也就是说,如果拷贝过来的属性的值是对象等复合属性,那么只能拷贝过来一个引用。
const obj1 = {
a: {
b: 1}};
const obj2 = Object.assign({
}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
应用场景
1、为对象添加属性
class Point{
constructor(x,y){
Object.assign(this,{x,y});
}
}
上面的方法可以为对象Point类的实例对象添加属性x和属性y。
2、为对象添加方法
// 方法也是对象
// 将两个方法添加到类的原型对象上
// 类的实例会有这两个方法
Object.assign(SomeClass.prototype,{
someMethod(arg1,arg2){...},
anotherMethod(){...}
});
将方法添加到类的原型对象上后,类的实例能继承这两个方法。
3、克隆对象
//克隆对象的方法
function clone(origin){
//获取origin的原型对象
let originProto = Obejct.getPrototypeOf(origin);
//根据原型对象,创建新的空对象,再assign
return Object.assign(Object.create(originProto),origin);
}
4、为属性指定默认值
// 默认值对象
const DEFAULTS = {
logLevel : 0,
outputFormat : 'html'
};
// 利用assign同名属性会覆盖的特性,指定默认值,如果options里有新值的话,会覆盖掉默认值
function processContent(options){
options = Object.assign({},DEFAULTS,options);
console.log(options);
//...
}
处于assign浅拷贝的顾虑,DEFAULTS对象和options对象此时的值最好都是简单类型的值,否则函数会失效。
const DEFAULTS = {
url: {
host: 'example.com',
port: 7070
},
};
processContent({ url: {port: 8000} })
// {
// url: {port: 8000}
// }
上面的代码,由于url是对象类型,所以默认值的url被覆盖掉了,但是内部缺少了host属性,形成了一个bug。
补充
转对象
扫描二维码关注公众号,回复:
15899269 查看本文章
Object(true) // {[[PrimitiveValue]]: true}
Object(10) // {[[PrimitiveValue]]: 10}
Object('abc') // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}