资讯专栏INFORMATION COLUMN

浅析深度克隆(deepclone)

yhaolpz / 2445人阅读

摘要:深度克隆方法,返回一个新的克隆对象这里得说明深拷贝与钱拷贝的区别,浅拷贝是复制一个对象的引用,深拷贝是一个新的对象,与原对象有着不同的内存地址方法一通过递归遍历一个对象,返回一个新的对象深拷贝要深拷贝的值判断某个对象是否含有指定的属性该方法

深度克隆方法,返回一个新的克隆对象
这里得说明深拷贝与钱拷贝的区别,浅拷贝是复制一个对象的引用,深拷贝是chone一个新的对象,与原对象有着不同的内存地址

方法一
通过递归遍历一个对象,返回一个新的对象

/**
 * 深拷贝
 * @param {*} target 要深拷贝的值
 */
function deepclone(target) {
  if (typeof target !== "object") return target;

  let obj;
  if (!Array.isArray) {
    Array.isArray = function(arg) {
      return Object.prototype.toString.call(arg) === "[object Array];";
    };
  }
  if (Array.isArray(target)) {
    obj = [];
  } else {
    obj = {};
  }
  for (let prop in target) {
    // obj.hasOwnProperty 判断某个对象是否含有指定的属性
    // 该方法会忽略掉从原型链上继承的属性
    if (target.hasOwnProperty(prop)) {
      if (typeof target === "object") {
        obj[prop] = deepclone(target[prop]);
      } else {
        obj[prop] = target[prop];
      }
    }
  }
  return obj;
}

console.log(deepclone({ a: 1, b: { c: 2 } })); // 打印 { a: 1, b: { c: 2 } }
console.log([1, 23, { a: 2 }]); // 打印 [1, 23, { a: 2 }]
console.log(deepclone(5)); // 打印 5

方法二
通过hack方式实现

function deepclone(target) {
  return JSON.parse(JSON.stringify(target));
}
console.log(deepclone({ a: 1, b: { c: 2 } })); // 打印 { a: 1, b: { c: 2 } }
console.log([1, 23, { a: 2 }]); // 打印 [1, 23, { a: 2 }]
console.log(deepclone(5)); // 打印 5

方法三
通过Object.getPrototypeOf() 获取目标对象的原型,通过Object.assign()生成一个新的对象

function deepclone(target) {
  if (typeof target !== "object") return target;
  return Object.assign(
    {},
    Object.create(Object.getPrototypeOf(target)),
    target
  );
}

console.log(deepclone({ a: 1, b: { c: 2 } })); // 打印 { a: 1, b: { c: 2 } }
console.log([1, 23, { a: 2 }]); // 打印 [1, 23, { a: 2 }]
console.log(deepclone(5)); // 打印 5

方法四
通过Object.getPrototypeOf() 获取目标对象的原型,通过扩展运算符以及proto来实现深度克隆(仅适用于浏览器端)

function deepclone(target) {
  if (typeof target !== "object") return target;
  return {
    __photo__: Object.getPrototypeOf(target),
    ...target
  };
}

console.log(deepclone({ a: 1, b: { c: 2 } }));
console.log([1, 23, { a: 2 }]);
console.log(deepclone(5));

各种方式都有自己的优劣,以及适用场景,在不知道怎么选的情况下,选择方法一、三比较靠谱

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106475.html

相关文章

  • 如何深度克隆一个对象

    摘要:如何深度克隆一个对象在我们日常工作中经常会遇到需要去克隆一个对象比如多个地方用到的公共的图表基本参数的配置相信很多人会想到用和方法去克隆一个对象,这个可以明确告诉大家这些都是些不靠谱的浅度克隆。 如何深度克隆一个对象 在我们日常工作中经常会遇到需要去克隆一个对象比如多个地方用到的公共的图表基本参数的配置 相信很多人会想到用 Object.assign, JSON.stringify 和...

    TIGERB 评论0 收藏0
  • js深度克隆的几种方法

    摘要:方法一老老实实敲代码法迭代法,适用于所有方法二利用将对象序列化字符串,再使用来反序列化还原对象缺点如果里面有时间对象,则后再的结果,时间将只是字符串的形式。简而言之,第一层实现了深度拷贝,后续层次还是浅拷贝 方法一 老老实实敲代码法(迭代法,适用于所有) function deepClone(obj) { let newObj = Array.isArray(obj) ? [...

    Pluser 评论0 收藏0
  • 【转】JavaScript 对象的深度克隆

    摘要:在聊以下简称深度克隆之前,我们先来了解一下中对象的组成。克隆或者拷贝分为种浅度克隆深度克隆。浅度克隆基本类型为值传递,对象仍为引用传递。 该文转载自http://www.cnblogs.com/zichi/p/4568150.html,有部分修改。 在聊JavaScript(以下简称js)深度克隆之前,我们先来了解一下js中对象的组成。在 js 中一切实例皆是对象,具体分为 原始类型 ...

    JowayYoung 评论0 收藏0
  • js clone

    摘要:克隆的概念浅克隆原始类型为值传递,对象类型仍为引用传递。深度克隆检验参数,如果不是对象直接返回原型链上继承过来的属性无法通过检测到,返回。方法用于将字符串解析为,可以任意转换生成的值及其属性,并返回值。 克隆的概念 浅克隆:原始类型为值传递,对象类型仍为引用传递。深克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。 浅克隆就是将栈内存中...

    diabloneo 评论0 收藏0
  • lodash之cloneDeep浅析

    摘要:浅拷贝和深拷贝本质上的原因是对象引用的是地址,直接赋值会吧引用地址也复制给新值。深拷贝是会递归源数据,吧新值得引用地址给换掉。对递归对递归调用是否是类型数组这里主要是会有个的特殊数组返回的特殊数组其他方法库或等 浅拷贝和深拷贝 本质上的原因是对象引用的是地址,直接赋值会吧引用地址也复制给新值。浅复制只会将对象的各个属性进行依次复制,会把引用地址也复制。深拷贝是会递归源数据,吧新值得引用...

    chemzqm 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<