首页 > JS如何深度复制对象和数组,避免指针变量引用修改值

JS如何深度复制对象和数组,避免指针变量引用修改值

//自定义深度复制对象or数组的递归方法----------------------------------------
let copyObjOrArr = o => {let isArray = o instanceof Array;let isObject = o instanceof Object;if (!isObject) return o;     let n = (isArray ? [] : {});for (let k in o) n[k] = copyObjOrArr(o[k]);     return n;
}//测试----------------------------------------var obj={a:1};
var arr=[1,2,3];
var obj_new =copyObjOrArr(obj);
var arr_new =copyObjOrArr(arr);console.log(obj_new);
console.log(arr_new);

如上图所示这样复制对象or数组就不会产生指针变量那种修改的情况了 


BUT!

我依然觉得上面的代码肽冗余,本质上我们只要复制了内容,并且保证变量指向的内存地址也发生改变就可以了

此刻,我想起了JSON.parse(JSON.stringify( objectOrArray )),这个把对象转为字符串再反转为对象的过程,就可以完成一次内存地址变更,于是有了代码

var obj={a:1};
var arr=[1,2,3];
var obj_new = JSON.parse(JSON.stringify( obj ));
var arr_new = JSON.parse(JSON.stringify( arr ));//测试----------------------------------------var obj={a:1};
var arr=[1,2,3];
var obj_new =copyObjOrArr(obj);
var arr_new =copyObjOrArr(arr);console.log(obj_new);
console.log(arr_new);

实验结果完美!

JSON.parse(JSON.stringify( objectOrArray ))完全无需额外定义方法,最原汁原味的骚操作!

这样复制一下,你的对象就不再是以前的对象,你的数组也不再是以前的数组了!!!




 那么问题来了,为啥不这样操作,就会导致变量修改了会影响被复制的变量值呢?js中Object类型和Array类型的变量被赋值(复制)给其他变量后,修改被赋值(复制)的新变量的值,会影响原始变量的值,这是为什么呢?_你挚爱的强哥❤给你发来1条消息❤-CSDN博客JavaScript中的Object和Array都是指针变量类型,例如我声明let obj={a:1};let arr=[1,2,3];其中的obj和arr存放的仅仅是对应的对象和数组内容所存放的内存地址值当你用以下代码赋值给另外的新变量的时候let obj={a:1};let arr=[1,2,3];let obj_new=obj;let arr_new=arr;我们对 obj_new 和 arr_new 的内容进行修改,原始的 obj 和 arr 变量的值也会https://s-z-q.blog.csdn.net/article/details/121134588

更多相关:

  • 题目:最小的k个数 入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 示例 1: 输入:arr = [3,2,1], k = 2 输出:[1,2] 或者 [2,1] 示例 2: 输入:arr = [0,1,2,1], k = 1 输出:[0...

  • var array = {/* 数组求和*/sum: arr => eval(arr.join("+")),/* 判断一个数组(支持一个字符串)里面的是否有任何一个元素被包含在了某个字符串里面 */isStringContain(str, arr) {Array.isArray(arr) || (arr = [arr]);for (v...

  • 经过调研发现,对任意无序整数数组,快速排序有两种实现方法,这里简单阐述下思路: 思路一:随意选择一个基准元,一般选择数组的起始元或末尾元,Weiss这本书上特意搞了个算法来选择基准元,……,总之就是基准元的选择要尽量随机。选定基准元之后,比如选择数组起始元为基准元,从数组右边开始,向左边遍历,遇到比基准元大的跳过,直至遇到比基准元小...

  • 下面给出这段时间我苦心研究验证过的十种经典排序算法的C语言版本,即下面的排序算法: 插入排序,shell排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,桶排序,基数排序和计数排序。整理出来以作备忘,不足之处,欢迎大家批评指正!其中计数排序分别给出了不稳定和稳定两种排序算法,测试时,使用随机生成大数组和随机手动输入的方法来测试。...

  • /*js中遍历对象属性*/ function printObject(obj) {var temp = "";for (var key in obj) {temp += key + ":" + obj[key] + " ";}return temp; }/*测试用例*/ var obj = {"a": "1", "b": "2"};...

  •     /* @flow */ // Object.freeze 使得这个对象不能增加属性, 修改属性, 这样就保证了这个对象在任何时候都是空的 export const emptyObject = Object.freeze({}) /*** Check if a string starts with $ or _ ascii u...

  • 当使用jquery1.3以上版本时,进行ajax参数传值时,会出现以下的一个错误:  ognl.ExpressionSyntaxException: Malformed OGNL expression: f[] [ognl.ParseException: Encountered " "]" "] "" at line 1, col...

  • 在IssueVision的命令模式中有如下代码(PatternsCommander.cs)  public static void Connect(ToolBarButton button, Command command)  {   ToolBarButtonCommander unused = new ToolBarButto...

  • 菜鸟一枚,正在学习C++ Gui Qt4,整理很零碎,欢迎批评指正   1.窗口标题: QWidget *window = new QWidget; window->setWindowTitle("Enter Your Age"); **************************************** 关于标题...

  • 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 总体思路是: 比较两个链表头节点,较小的插入新链表指针之后,同时较小链表指针向后移动一位 实现如下: ListNode* mergeTwo...

  • 1.直接调用微软socket对象处理 static void Main(string[] args){try{IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });//在3721端口新建一个TcpListener对象TcpListener listener = new...

  •   现在很多地方都会用到zookeeper, 用到它的地方就是为了实现分布式。用到的场景就是服务注册,比如一个集群服务器,需要知道哪些服务器在线,哪些服务器不在线。   ZK有一个功能,就是创建临时节点,当机器启动应用的时候就会连接到一个ZK节点,然后创建一个临时节点,那么通过获取监听该路径,并且获取该路径下的节点数量就知道有哪些服务...

  • 前台到后台java时data日期类型的转化 在实体类中用@DataTimeFormat,这样设置即使传过来是空的字符串也是可以转的,要和前面传过来的格式一致,如 @XmlElement(name="BeginDate") @DateTimeFormat(pattern="yyyy-MM-dd") private Date begin...