ES6 Object.assign() 浅拷贝

73 阅读2分钟

摘要

  • 用于对象的合并
  • 注意事项:
    • 只拷贝自身属性,不拷贝继承属性,不拷贝【不可枚举】的属性
    • 浅拷贝:值是对象的话,只拷贝引用
    • 数组:转为key是下标的对象
    • 取值函数:只进行值的复制
    • key同名:后面会覆盖前面
  • 参数:
    • 只有一个参数:直接返回
    • 参数不是对象:转成对象
    • undefined 和null在首参数:报错
    • Symbol:也会被拷贝

1. 定义

用于对象的合并,把源对象(非首参数)复制到目标对象(首参数),源对象可以多个

2. 参数

const obj = {a: 1};
// 1. 一个参数,就返回本身
Object.assign(obj) 
// 2. 参数是非对象:会转成对象 Number{2} 
Object.assign(2)
// 3. 目标对象是undefined || null :报错
Object.assign(null)
// 4. 源对象:除了字符串、Symbol以外的基本数据类型,不生效

image.png

3. 注意事项

3.1 浅拷贝

浅拷贝:如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用


const person={
    name:"弟弟",
    school:{
        level1:{
            name:"清华大学"
        }
    }
}
// 进行拷贝
const person1 = Object.assign({}, person);

// 拷贝后分别改动person浅层和深层的值
person.name = "哥哥";
person.school.level1 = "北京大学"

// 那么打印的 person1的值 是什么呢 ? 
console.log(person1.name)//  "弟弟"
console.log(person1.school.level1)//  "北京大学"

源对象的key对应的value:

  • 是基本类型的话,会拷贝值。
  • 是对象的话,则拷贝引用(也就是对源对象的改变会影响到目标对象的值)

3.2 同名替换处理:

const target = { a: { b: '1', d: '2' } } 
const source = { a: { b: 'hello' } } 
// 只会取后面source的值
Object.assign(target, source) // { a: { b: 'hello' } }

会整个替换,容易丢失

3.3 数组的处理:转换成{下标:值}

Object.assign([A, B, C], [4, 5]) // [4, 5, C]

Object.assign()把数组视为{0:A,1:B,3:C},源数组{0:4, 1:5}。结合同名替换规则,结果就是[4, 5, C]

3.4 取值函数的处理:复制执行后的值

复制执行后的值,而不是取值函数本身


const source = { 
   get foo() { return 1 } 
}; 
Object.assign({}, source) // { foo: 1 }

常见用途:

  1. 为对象添加属性
  2. 为对象添加方法
  3. 克隆对象
  4. 合并多个对象
  5. 为属性指定默认值

Class Point { 
    constructor(x, y) { 
        Object.assign(this, {x, y}); 
    }
}

Object.assign(SomeClass.prototype, 
    { 
        someMethod(arg1, arg2) { ··· }, 
        anotherMethod() { ··· } 
    }
);

function clone(source){
  return Object.assign({}, source)
}

function merge(sources){
   return Object.assign({}, {...sources})
}

function processContent(options){
   Object.assign({}, DEFAULT, options)
}