随时记|Object.assign()

Object.assign()的基本使用 && 语法

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象,他返回目标对象

  • 参数:target 目标对象,source 源对象
  • 返回值:目标对象
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }

console.log(target === returnedTarget) // true

问题1: 返回值是目标对象吗?

下面代码很好地回答了这个问题

console.log(target === returnedTarget) // true

问题2:参数为非对象会发生什么?

(1)目标对象为null或者undefined

在这里插入图片描述
直接报错,说明目标对象不能为null或者undefined

(2)源对象中有null或者undefined

在这里插入图片描述
在这里插入图片描述
从打印结果来看,nullundefined被忽略了

(3)源对象中有boolean,number, string, 数组怎么处理?

在这里插入图片描述
在这里插入图片描述
从打印结果看,boolean number string都被忽略了,而数组则转换为了‘index’:value的形式
这是为什么呢?这是因为检索到源对象中含有非数组的值的时候,会先用Object对这些值进行包装,
我们看数组被包装后的样子:

console.log(Object.getOwnPropertyDescriptors(Object([1,2,3])));
/**
 * {
    '0': { value: 1, writable: true, enumerable: true, configurable: true },
    '1': { value: 2, writable: true, enumerable: true, configurable: true },
    '2': { value: 3, writable: true, enumerable: true, configurable: true },
    length: { value: 3, writable: true, enumerable: false, configurable: false }
    } 
 * **/

而number则为

console.log(Object(123));  // [Number: 123]
console.log(Object.getOwnPropertyDescriptors(Object(123))); // {}

问题3: 继承属性和不可枚举属性是不能拷贝的

看下面这个例子:

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const obj = Object.create({foo:1}, {
    bar:{
        value:'hello',   // 不可枚举
    },
    baz:{
        value:'hi',
        enumerable: true,   // 可枚举
    },
});

console.log(obj);

const returnedTarget = Object.assign(target, obj);

console.log(returnedTarget);

在这个例子中,我们使用Object.create()创建了obj, 其中{foo:1}是新建对象obj的原型,bar不可枚举,而baz可枚举,我们将obj作为源对象assign给目标对象target的时候,返回的结果为:
在这里插入图片描述
说明:继承属性和不可枚举属性是不能拷贝的

问题4:Object.assign()是浅拷贝还是深拷贝?

当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝

(1)一级属性

let obj1 = {
    name:'Katrina',
    age:18,
};

let obj2 = Object.assign({}, obj1);

console.log(obj1, obj2);   // obj1 = { name: 'Katrina', age: 18 }     obj2 = { name: 'Katrina', age: 18 }

obj1.name = 'Jack';   // 修改obj1中的name

console.log(obj1, obj2);  // obj2未发生改变  obj1 = { name: 'Jack', age: 18 }  obj2 = { name: 'Katrina', age: 18 }

(2)二级属性

let obj1 = {
    name:'Katrina',
    age:18,
    family:{
        father:'Jack', 
        mother:'Mary',
    }
};

let obj2 = Object.assign({}, obj1);

console.log(obj1, obj2);  
// obj1 = { name: 'Katrina', age: 18, family: { father: 'Jack', mother: 'Mary' } }  obj2 = { name: 'Katrina', age: 18, family: { father: 'Jack', mother: 'Mary' } }

obj1.family.father = 'KK';  // 修改family中的father

console.log(obj1, obj2);  // obj2发生改变  
// obj1 = { name: 'Katrina', age: 18, family: { father: 'KK', mother: 'Mary' } }  obj2 = { name: 'Katrina', age: 18, family: { father: 'KK', mother: 'Mary' } }

问题5:合并同对象有同属性怎么变化?

let obj1 = {
    name:'Katrina',
    age:18,
};

let obj2 = {
    name:'Jack',
    age:19,
    gender:'Female',
};


let obj3 = Object.assign(obj2, obj1);

console.log(obj3);   // { name: 'Katrina', age: 18, gender: 'Female' }

显然是发生了替换

问题6:异常会打断后续拷贝任务

const target = Object.defineProperty({}, "foo", {
    value: 1,
    writable: false
}); // target 的 foo 属性是个只读属性。

Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});
// TypeError: "foo" is read-only
// 注意这个异常是在拷贝第二个源对象的第二个属性时发生的。

console.log(target.bar);  // 2,说明第一个源对象拷贝成功了。
console.log(target.foo2); // 3,说明第二个源对象的第一个属性也拷贝成功了。
console.log(target.foo);  // 1,只读属性不能被覆盖,所以第二个源对象的第二个属性拷贝失败了。
console.log(target.foo3); // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的。
console.log(target.baz);  // undefined,第三个源对象更是不会被拷贝到的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值