js数组浅拷贝_js数组深度复制

js数组浅拷贝_js数组深度复制JavaScript实现数组的深拷贝、浅拷贝vararr=[‘old’,1,true,null,undefined];varnew_arr=arr.concat();//或者varnew_arr=arr.slice()也是一样的效果;new_arr[0]=’new’;console.log(arr);//["ol……

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

浅拷贝:创建一个新的对象,来接受重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象;但如果属性是引用数据类型,复制的就是内存中的地址,如果其中一个对象改变了这个内存中的地址,会影响到另一个对象,因为两者共同指向同一个地址。

数组的浅拷贝
可用concat、slice返回一个新数组的特性来实现拷贝

var arr = ['old', 1, true, null, undefined];
var new_arr = arr.concat(); // 或者var new_arr = arr.slice()也是一样的效果;
new_arr[0] = 'new';
console.log(arr); // ["old", 1, true, null, undefined]
console.log(new_arr); // ["new", 1, true, null, undefined]

浅拷贝,还可以用Object.assign()方法实现

let target = { 
   };
let source = { 
    a: { 
    b: 2 } };
Object.assign(target, source);
console.log(target); // { a: { b: 10 } }; 
source.a.b = 10; 
console.log(source); // { a: { b: 10 } }; 
console.log(target); // { a: { b: 10 } };

但是如果数组嵌套了对象或者数组的话用concat、slice拷贝只要有修改会引起新旧数组都一起改变了,比如:

var arr = [{ 
   old: 'old'}, ['old']];
var new_arr = arr.concat();
arr[0].old = 'new';
new_arr[1][0] = 'new';
console.log(arr); // [{old: 'new'}, ['new']]
console.log(new_arr); // [{old: 'new'}, ['new']]

下面是浅拷贝一个通用方法,实现思路:遍历对象,把属性和属性值都放在一个新的对象里

var shallowCopy = function (obj) { 
   
  // 只拷贝对象
  if (typeof obj !== 'object') return;
  // 根据obj的类型判断是新建一个数组还是一个对象
  var newObj = Array.isArray(obj) ? [] : { 
   };
  // 遍历obj,并且判断是obj的属性才拷贝
  for (var key in obj) { 
   
    if (obj.hasOwnProperty(key)) { 
   
      newObj[key] = obj[key];
    }
  }
  return newObj;
}

// 如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。这种叫浅拷贝
// 深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。

数组的深拷贝
方法一:JSON.stringify()不仅可拷贝数组还能拷贝对象(但不能拷贝函数,也不能解决循环引用问题)

var arr = ['old', 1, true, ['old1', 'old2'], { 
   old: 1}]
var new_arr = JSON.parse(JSON.stringify(arr))
console.log(new_arr);

方法二:递归。下面是深拷贝一个通用方法,实现思路:拷贝的时候判断属性值的类型,如果是对象,继续递归调用深拷贝函数

var deepCopy = function(target) { 
   
  // 只拷贝对象
  if (typeof target !== 'object') return target;
  // 根据obj的类型判断是新建一个数组还是一个对象
  var result = Array.isArray(obj) ? [] : { 
   };
  for (var key in target) { 
   
    // 遍历obj,并且判断是obj的属性才拷贝(不能拷贝原型对象的属性)
    if (target.hasOwnProperty(key)) { 
   
      // 判断属性值的类型,如果是对象递归调用深拷贝
      result[key] = typeof target[key] === 'object' ? deepCopy(target[key]) : target[key];
    }
  }
  return result;
}

其中上述方法一、方法二都解决不了循环引用的问题。
方法三,结合map(将方法二的递归改造,解决循环引用问题):

var deepCopy = function (target, map = new Map()) { 
   
  // 只拷贝对象
  if (typeof target !== "object") return target;
  // 克隆数据之前,先判断之前是否有克隆过(解决循环引用的问题)
  let cache = map.get(target);
  if (cache) { 
   
    return cache;
  }
  // 根据obj的类型判断是新建一个数组还是一个对象
  var result = Array.isArray(target) ? [] : { 
   };
  // 将新的结果存到容器中
  map.set(target, result);
  for (var key in target) { 
   
    // 遍历obj,并且判断是obj的属性才拷贝(不能拷贝原型对象的属性)
    if (target.hasOwnProperty(key)) { 
   
      // 判断属性值的类型,如果是对象递归调用深拷贝
      result[key] =
        typeof target[key] === "object"
          ? deepCopy(target[key], map)
          : target[key];
    }
  }
  return result;
};

// 测试代码
let obj = { 
    a: 1, b: [6, 8], c: { 
    e: 3 } };
obj.b.push(obj.c);
obj.c.h = obj.b;
let obj1 = deepCopy(obj);
console.log(obj);
console.log(obj1);
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187063.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java与数据库连接的步骤_java与数据库的连接怎么实现

    java与数据库连接的步骤_java与数据库的连接怎么实现1.加载驱动Class.forname(数据库驱动名);2.建立数据库连接使用DriverManager类的getConnection()静态方法来获取数据库连接对象,其语法格式如下所示:Connectionconn=DriverManager.getConnection(Stringurl,Stringuser,Stringpass);其中url–数据库连接字符串….

    2025年12月8日
    4
  • SOP是什么?SOP的作用是什么?如何编写SOP?

    SOP是什么?SOP的作用是什么?如何编写SOP?SOP是由StandardOperationProcedure这三个英文单词的首个字母组合而成。也就是以统一化的标准将操作流程的步骤和要求罗列出来,用于指导和规范日常工作。SOP的核心,就是把特定流程的关键问题细化及量化。SOP是以文件的方式归纳总结操作人员在实际生产过程中的具体操作步骤和应当要注意的事项,它是车间现场操作人员的作业指导模板,也是质量检验人员用于检测指导工作的依据。SOP的作用:1、把企业长期累积的经验技术记录归纳,汇总成简单易懂的标准化文件,即使出现操作人员变动也不会使已有的技

    2022年5月9日
    58
  • linux树莓派连接wifi密码,树莓派 连接wifi与路由器ip绑定

    linux树莓派连接wifi密码,树莓派 连接wifi与路由器ip绑定树莓派连接wifi与路由器ip绑定,先推荐几个手机软件1.JuiceSSH橘子ssh软件手机连上路由器就可以控制局域网内的树莓派2.VNCViewer远程桌面软件VNC也是连接局域网的树莓派这几个软件还是很好用的,不想开电脑的时候,也能控制树莓派——————————————————————-…

    2022年5月7日
    53
  • 学习 Web 开发技术的16个最佳教程网站和博客

    学习 Web 开发技术的16个最佳教程网站和博客互联网经过这么多年的发展,已经出现了众多的Web开发技术,像.Net/Java/PHP/Python/Ruby等等。对于Web开发人员来说,不管是初学者还是有一定经验的开发人员都需要时刻学

    2022年8月6日
    3
  • NPOI导出Excel并下载到客户端

    NPOI导出Excel并下载到客户端利用NPOI导出Excel,把Excel发送到客户端

    2022年6月22日
    72
  • 一加6手机图片中的文字如何识别?[通俗易懂]

    一加6手机图片中的文字如何识别?[通俗易懂]一加6手机很多人都想买吧?买了手机的朋友手机里就有很多照片,一加6手机图片中的文字如何识别?文字识别都是识别大量的文字,减轻办公人员负担的。1在手机上输入PDF阅读器,然后开始识别相册图片的文字2打开就是这样的界面,找到倒数第2个的小功能3选择拍照识别中的相册,接下来添加图…

    2022年5月1日
    440

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号