Js使用Object.assign()对象的复制、合并、封装等操作

时间: 2018-01-02阅读: 830标签: 复制

OObject.assign()方法可将所有可枚举属性的值从一个或多个源对象复制到目标对象,它将返回目标对象。 其中对象的继承属性和不可枚举属性是不能拷贝的。


对象的复制

var obj= { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); //{ a: 1 }

说明:assign复制的是属性值,不能复制源对象中具有引用其它对象的属性值,所以不能使用它来实现深拷贝。实现深拷贝请参考:js中深拷贝和浅拷贝的区别及原理

在官方文档中写得一个Polyfill ,代码加了点注释如下:

if (!Object.assign) {
    // 定义assign方法
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) { // assign方法的第一个参数
      'use strict';
      // 第一个参数为空,则抛错
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      // 遍历剩余所有参数
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        // 参数为空,则跳过,继续下一个
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        // 获取改参数的所有key值,并遍历
        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          // 如果不为空且可枚举,则直接浅拷贝赋值
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

从上面代码可以看出Object.assign()只对顶层属性做了赋值,没有继续做递归把所有下一层的属性做深拷贝。


对象的合并和封装

var obj1 = { a: 1,};
var obj2 = { b: 2, c: 2 };
var obj3 = { c: 3 };
var obj = Object.assign({}, obj1, obj2, obj3,null,undefined,"abc",{[Symbol("sbl")]:4});
console.log(obj); //输出{0: "a", 1: "b", 2: "c", a: 1, b: 2, c: 3}
VM1253:5 {0: "a", 1: "b", 2: "c", a: 1, b: 2, c: 3, Symbol(sbl): 4}

说明:1.对象的属性被后续参数中具有相同属性的其他对象覆盖;2.null、undefined会被忽略;3.字符串会被封装成单字符的可枚举属性数组。