Object.assign()详解

简介: Object.assign()详解

1、Object.assign()是什么?

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

       tips:在JavaScript中枚举属性简单来说就是指对象中的属性是否可以被遍历出来,是属性的enumerable值决定的

2、基本用法

const target = { a: 1, b: 2 };
const source = { b: 3, c: 4 };
const source2 = { c: 5, d: 6 };
const currentTarget = Object.assign(target, source, source2);
console.log(currentTarget);
// currentTarget:  {a: 1, b: 3, c: 5, d: 6}

20210527153548522.png

Object.assign方法的第一个参数是目标对象,后边的其他参数都是源对象;

tips:

1、如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。

2、Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。

3、注意目标自身也会改变

20210527153548522.png

如果只有一个参数,Object.assign会直接返回该参数

const target = { a: 1, b: 2 };
const currentTarget = Object.assign(target);
console.log(currentTarget);
//{a: 1, b: 2}

该参数不是对象会先转为对象,然后return;(undefined || unll 出现在target(源对象)位置无法转换为对象会报错)

const currentTarget = Object.assign(10);
console.log(currentTarget);
//Number {10}

注意,Object.assign 不会在那些source对象值为 nullundefined 的时候抛出错误。

其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。

const source1 = "aaa";
const source2 = false;
const source3 = 666;
const currentTarget = Object.assign({}, source1, source2, source3);
console.log(currentTarget);
//{0: "a", 1: "a", 2: "a"}

20210527153548522.png

Symbol 类型的属性也会被拷贝。

const target = { a: "111" };
const source1 = { [Symbol("6")]: 666 };
const currentTarget = Object.assign(target, source1);
console.log(currentTarget);
//{a: "111", Symbol(6): 666}

继承属性和不可枚举属性是不能拷贝的

const obj = Object.create({foo: 1}, { // foo 是个继承属性。
    bar: {
        value: 2  // bar 是个不可枚举属性。
    },
    baz: {
        value: 3,
        enumerable: true  // baz 是个自身可枚举属性。
    }
});
const currentTarget= Object.assign({}, obj);
console.log(currentTarget); // { baz: 3 }

出现异常会打断后续的copy任务

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,第三个源对象更是不会被拷贝到的。

深拷贝问题

针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是(可枚举)属性值。

假如源值是一个对象的引用,它仅仅会复制其引用值。

const log = console.log;
function test() {
  let obj1 = { a: 0 , b: { c: 0}};
  let obj2 = Object.assign({}, obj1);
  log(JSON.stringify(obj2));
  // { a: 0, b: { c: 0}}
  obj1.a = 1;
  log(JSON.stringify(obj1));
  // { a: 1, b: { c: 0}}
  log(JSON.stringify(obj2));
  // { a: 0, b: { c: 0}}
  obj2.a = 2;
  log(JSON.stringify(obj1));
  // { a: 1, b: { c: 0}}
  log(JSON.stringify(obj2));
  // { a: 2, b: { c: 0}}
  obj2.b.c = 3;
  log(JSON.stringify(obj1));
  // { a: 1, b: { c: 3}}
  log(JSON.stringify(obj2));
  // { a: 2, b: { c: 3}}
  // Deep Clone
  obj1 = { a: 0 , b: { c: 0}};
  let obj3 = JSON.parse(JSON.stringify(obj1));
  obj1.a = 4;
  obj1.b.c = 4;
  log(JSON.stringify(obj3));
  // { a: 0, b: { c: 0}}
}
test();

同名属性的替换

对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。

const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }
相关文章
|
5月前
|
JavaScript 前端开发
object.assign
object.assign
33 0
|
6月前
|
JSON JavaScript 前端开发
Object.assign
Object.assign
47 1
|
JavaScript
js的Object.assign坑
js的Object.assign坑
63 0
|
前端开发 索引
Array.prototype.at
Array.prototype.at
82 0
|
Java 数据库连接 mybatis
@TableId(type = IdType.ASSIGN_ID)
@TableId(type = IdType.ASSIGN_ID)
172 1
Object.assign详解
Object.assign详解
263 0
|
JavaScript 开发者
ES6之Object.assign()用法,Object.assign()到底是浅拷贝还是深拷贝?
ES6之Object.assign()用法,Object.assign()到底是浅拷贝还是深拷贝?
8702 1
|
前端开发
前端学习案例1-object.assign
前端学习案例1-object.assign
66 0
前端学习案例1-object.assign
|
前端开发
前端学习案例5-object.assign的应用
前端学习案例5-object.assign的应用
63 0
前端学习案例5-object.assign的应用
|
前端开发
前端学习案例2-object.assign之2
前端学习案例2-object.assign之2
63 0
前端学习案例2-object.assign之2