前端使用JSON.stringify实现深拷贝的巨坑详解

首先,需要明确深拷贝和浅拷贝的概念。

在JavaScript中,对象的赋值有两种方式:深拷贝和浅拷贝。浅拷贝只是将对象的引用复制给了新的变量,而深拷贝则是递归地复制对象及所有嵌套的子对象。

JSON.stringify可以将一个JavaScript对象序列化成一个JSON字符串,而JSON.parse则可以将一个JSON字符串反序列化成一个JavaScript对象。所以,看起来使用JSON.stringify和JSON.parse就可以实现深拷贝了,但是实际情况并非如此。

下面是使用JSON.stringify实现深拷贝的错误示例:

let obj = { a: 1, b: { c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
obj.b.c = 3;
console.log(newObj.b.c); // 输出结果为2,而不是期望的3

上面的代码中,obj对象中有一个嵌套的对象{ c: 2 },将obj对象通过JSON.stringify序列化成JSON字符串后,再通过JSON.parse将其反序列化成一个新的对象newObj。此时,obj对象中嵌套对象的值被修改后,newObj对象中的值并没有跟着改变。但是,如果嵌套的子对象{ c: 2 }中也含有嵌套的子对象,像这样:

let obj = { a: 1, b: { c: { d: 2}}};
let newObj = JSON.parse(JSON.stringify(obj));
obj.b.c.d = 3;
console.log(newObj.b.c.d); // 输出结果是3,而不是期望的2

此时,newObj对象中的值跟着被修改。这是因为,在JSON.stringify序列化时,嵌套的子对象并不会被递归地复制,而是仍然继续使用原来的引用,因为JSON.stringify无法序列化函数和对象的属性中具有undefined的值。这就会导致嵌套的子对象在后续的修改中也会被更改。因此,在使用JSON.stringify实现深拷贝时,需要特别注意这个坑。

下面是使用递归实现深拷贝的示例:

function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  var newobj = {}
  for (var key in obj) {
    newobj[key] = deepClone(obj[key]);
  }
  return newobj;
}

let obj = { a: 1, b: { c: { d: 2}}};
let newObj = deepClone(obj);
obj.b.c.d = 3;
console.log(newObj.b.c.d); // 输出结果为2,不会被后续修改影响到

上面的代码中,我们使用递归的方式实现深拷贝,确保了嵌套的子对象也得到了复制,不会因为后续的修改而发生变化。

总之,如果需要实现对象的深拷贝,使用JSON.stringify并不是可靠的方法,而是需要使用递归等其他方式来确保嵌套的子对象也被复制,避免出现意外的错误。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:前端使用JSON.stringify实现深拷贝的巨坑详解 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • JavaScript实现的浏览器下载文件的方法

    现在我将为你详细讲解JavaScript实现的浏览器下载文件的方法。 1. 使用原生XMLHttpRequest对象 基本原理 通过XMLHttpRequest对象发送HTTP请求,将服务器返回的文件内容存储在本地BLOB对象中,然后使用URL.createObjectURL()生成一个文件的URL,最后在浏览器中打开这个URL,并设置download属性即…

    JavaScript 2023年5月27日
    00
  • 使用JS中的Replace()方法遇到的问题小结

    使用JS中的Replace()方法是对字符串进行替换操作的常见方法,但在使用过程中,可能会遇到一些问题,本文将对使用过程中可能会遇到的问题进行小结,希望能帮助读者更好地掌握该方法的使用。 问题一:正则表达式符号的转义问题 在进行字符串的替换操作时,可能需要使用到正则表达式符号,例如点号(.)、问号(?)等。但是,在使用时,这些符号需要进行转义,如用“.”代替…

    JavaScript 2023年5月18日
    00
  • 基于JavaScript 类的使用详解

    基于 JavaScript 类的使用详解 JavaScript 的 Class 定义是一种专门为对象的构建提供的语法糖。在ES6之前,JavaScript没有类(class)的概念,只能通过构造函数和原型对象来实现。 类的定义和语法 定义一个类可以使用 class 关键字,后面跟着类名和一对大括号 {}。 大括号内部可以定义类的属性和方法。使用 constr…

    JavaScript 2023年5月18日
    00
  • html5 canvas js(数字时钟)实例代码

    下面是“HTML5 Canvas JS(数字时钟)实例代码”的完整攻略。 前置知识 在学习 HTML5 Canvas JS 时,需要具备 HTML 和 JavaScript 的基础知识。 步骤 步骤1:创建 HTML 文件 首先,创建一个 HTML 文件,并添加一个 canvas 标签以显示数字时钟。代码如下: <!DOCTYPE html> &…

    JavaScript 2023年5月27日
    00
  • JavaScript在浏览器标题栏上显示当前日期和时间的方法

    要在浏览器标题栏上显示当前日期和时间,我们可以使用JavaScript来动态显示。 步骤 获取当前日期和时间 使用Date对象获取当前日期和时间。可以使用如下代码获取当前日期和时间: var currentDatetime = new Date(); 格式化日期和时间 我们可以使用JavaScript的Date对象的方法来格式化日期和时间。使用toISOSt…

    JavaScript 2023年5月27日
    00
  • JavaScript获取页面元素的常用方法详解

    JavaScript获取页面元素的常用方法详解 在使用JavaScript编写网页交互逻辑时,获取页面元素是一个非常重要的操作,它可以让我们通过JavaScript来修改网页内容、处理用户交互等。下面是几种常用的获取页面元素的方法。 document.getElementById() 这是最基础的获取页面元素的方法之一,它可以通过指定HTML元素的ID属性来…

    JavaScript 2023年6月10日
    00
  • Python3实现飞机大战游戏

    Python3实现飞机大战游戏攻略 1. 准备工作 在开始编写游戏代码之前,需要安装好Pygame库。 在Windows系统下可以使用pip命令进行安装: pip install pygame 在Linux系统下可以使用以下命令安装: sudo apt-get install python3-pygame 2. 创建窗口 使用Pygame库创建游戏窗口的代码…

    JavaScript 2023年6月11日
    00
  • javascript实现考勤日历功能

    实现考勤日历功能的前置要求: 掌握HTML,CSS和JavaScript基础 了解Date对象及其相关方法 了解事件处理机制 下面开始我们的实现攻略: 步骤1:HTML骨架 我们需要先设计一个HTML骨架,用于放置后续动态生成的日历元素。 <div id="calendar"> <div class="head…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部