浅拷贝和深拷贝

2019-03-13  本文已影响0人  sansan大王

浅拷贝

创建一个对象,这个对象有着对原始对象属性的值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型, 拷贝的就是内存地址,所以其中一个对象改变会影响另外一个对象。

深拷贝

深拷贝会拷贝所有属性,并拷贝属性指向的动态分配内存,当对象和它所引用的对象一起拷贝时即发生深拷贝。

实现一个 Object.assign 大致思路如下:

1、判断原生 Object 是否支持该函数,如果不存在的话创建一个函数 assign,并使用 Object.defineProperty 将该函数绑定到 Object 上。

2、判断参数是否正确(目标对象不能为空,我们可以直接设置{}传递进去,但必须设置值)。

3、使用 Object() 转成对象,并保存为 to,最后返回这个对象 to。

4、使用 for..in 循环遍历出所有可枚举的自有属性。并复制给新的目标对象(使用 hasOwnProperty 获取自有属性,即非原型链上的属性)。

if (typeof Object.assign2 !='function') {

    Object.defineProperty(Object, 'assign2', {

        value:function (target) {

            if (target == null) {

                throw new TypeError('Cannot convert undefined or null to object');

            }

            let to = Object(target)

            for (let index =1; index < arguments.length; index++) {

                let nextSource = arguments[index];

                if (nextSource !=null) {

                    for (let nextKeyin nextSource) {

                        if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {

                            to[nextKey] = nextSource[nextKey]

                        }

                    }

                }

            }

            return to

        },

        writable:true,

        configurable:true

  })

}


深拷贝可以拆分成2步, 浅拷贝+递归,浅拷贝时判断属性值是否为对象,如果是就进行递归操作。

function cloneDeep(source) {

if (!isObject(source))return source; // 非对象返回自身

  var target = Array.isArray(source) ? [] : {};

  for(var keyin source) {

if (Object.prototype.hasOwnProperty.call(source, key)) {

if (isObject(source[key])) {

target[key] =cloneDeep(source[key]); // 注意这里

      }else {

target[key] = source[key];

      }

}

}

return target;

}

function isObject(obj) {

return typeof obj ==='object' && obj !=null;

}

上一篇下一篇

猜你喜欢

热点阅读