对象属性拷贝-Object.assign()


Object对象提供了一个复制对象属性的方法:Object.assign(),在我们需要将一个或多个对象属复制到目标对象时,可以使用这个方法。Object.assign()会把一个或多源对象的可枚举(可访问)属性复制给目标对象。


  1. assign()语法结构
  2. assign()与Underscore的_.extend方法
  3. assign()方法的使用


1. assign()语法结构

Object.assign(target, ...sources)
  • target,目标对象
  • sources,源对象,可以一个或多个
  • 返回值:复制sources属性后的target

Object.assign()方法会复制一或多个源对象的属性(可枚举)到目标对象,并返回目标对象。

Object.assign()方法只会拷贝源对象自身的并且可枚举的属性(即:该方法会执行源对象的访问器属性getter函数),并把复制值拷贝给目标对象,如果你想拷贝访问器属性本身,应该使用Object.getOwnPropertyDescriptor()Object.defineProperties()方法(字符串类型和symbol类型的属性都会被拷贝)。

异常

拷贝对象属性时可能会产生异常(如:目标对象的某个只读属性和源对象的某个属性同名时),这时会抛出一个TypeError异常并中断拷贝过程,异常之后的属性不会再被复制,但已复制的属性不受影响。Object.assign()会跳过值为nullundefined的源对象属性。


2. assign()与Underscore的_.extend方法

Underscore中提供一个便捷的与Object.assign()功能类似的方法:_.extend。该方法同样会复制源对象的属性到目标对象,但该方法遇到重复的属性名时会覆盖目标对象的属性值:

_.extend({domain: 'niefengjun.cn'}, {name: 'IT笔录'});
=> {domain: 'niefengjun.cn', name: 'IT笔录'}


3. assign()方法的使用

使用assign()方法浅拷贝一个对象:

var obj = {domain:'niefengjun.cn'};
var copy = Object.assign({}, obj);
console.log(copy); // domain:'niefengjun.cn'

使用assign()方法合并多个对象:

var obj1 = {domain:'niefengjun.cn'};
var obj2 = {name: 'IT笔录'};
var obj = Object.assign(obj1, obj2);
console.log(obj);  //{ domain: 'niefengjun.cn', name: 'IT笔录' }

assign()方法同样也可以用于复制symbol类型的属性:

var obj1 = {name: 'IT笔录'};
var obj2 = {[Symbol("domain")]: 'niefengjun.cn'};

var obj = Object.assign({}, obj1, obj2);
console.log(obj); // { name: 'IT笔录', [Symbol("domain")]: 'niefengjun.cn'}

不能用于继承和隐藏属性的复制:

var source = { // foo 是个继承属性。
  name: {
    value: 'IT笔录'  // name是个不可枚举属性
  },
  domain: {
    value: 'niefengjun.cn',
    enumerable: true  // domain是可枚举属性
  }
};
var obj = Object.create({foo: 1}, source);

var copy = Object.assign({}, obj);
console.log(copy); // { domain: 'niefengjun.cn' }