前端使用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日

相关文章

  • js实现touch移动触屏滑动事件

    首先,在JS中实现touch移动事件需要以下步骤: 1.监听touch事件,获取移动的距离及方向2.根据移动的距离及方向判断滑动操作:是垂直滑动还是水平滑动3.根据滑动的距离改变页面元素的位置4.结束滑动后执行相应的操作,比如改变元素的样式或者执行相关动画 下面是JS实现touch移动事件的完整示例: <!DOCTYPE html> <ht…

    JavaScript 2023年6月11日
    00
  • JS 实现倒计时数字时钟效果【附实例代码】

    JS 实现倒计时数字时钟效果是一个比较常见的前端特效,本文将为大家分享如何实现这个效果并附上实例代码。以下是完整攻略: 第一步:HTML 基础 首先,我们需要在 HTML 中创建一个数字时钟展示区域,可以选择一个 div 包含一个 h1 标签或者直接使用 h1 标签。具体代码如下: <div id="countdown-clock"…

    JavaScript 2023年5月27日
    00
  • JS简单判断字符在另一个字符串中出现次数的2种常用方法

    让我来介绍一下JS简单判断字符串在另一个字符串中出现次数的2种常用方法。下面将结合代码给出具体的示例: 1. 方法一:for循环遍历字符串 // 定义待匹配字符和被匹配字符 const targetStr = "hello"; const sourceStr = "hello world, hello everyone&quot…

    JavaScript 2023年5月28日
    00
  • JavaScript创建对象的几种方式及关于this指向问题

    当我们使用 JavaScript 开发应用时, 经常要通过创建对象来实现某些功能。JavaScript 中有多种方式可以创建对象,下面是几种常见的方法。 1. 字面量方式 最常见的创建对象的方式就是使用字面量方式,我们使用对象字面量来创建一个对象,并将其赋值给一个变量或常量。 const obj = { name: ‘Tom’, age: 20 } 对象字面…

    JavaScript 2023年5月27日
    00
  • javascript 两种声明函数的方式的分析

    我会为你进行详细的解释。 在JavaScript中有两种声明函数的方式: 函数声明 函数声明的语法如下: function 函数名称 (参数) { // 函数体 } 这种方式声明函数的特点是在代码块执行之前函数就已经存在。也就是说,无论在何处调用函数都是有效的。此外,函数声明不需要使用分号(;)来结束。 下面是一个简单的示例,演示了如何使用函数声明: fun…

    JavaScript 2023年5月27日
    00
  • Dwr3.0纯注解(纯Java Code配置)配置与应用浅析一之零配置文件化

    Dwr3.0纯注解(纯Java Code配置)配置与应用浅析一之零配置文件化 什么是Dwr3.0纯注解配置 Dwr(Direct Web Remoting) 是一种轻量级的远程框架,它可以实现web端的无刷新操作、异步处理,极大地提高了web应用的用户体验。 需要说明的是,这里提到的Dwr3.0纯注解配置,与使用传统的dwr.xml配置文件的方式相对。 Dw…

    JavaScript 2023年5月28日
    00
  • JavaScript字符串包含问题

    JavaScript字符串包含问题是指在一个字符串中,查找是否包含另一个字符串的问题。通常使用indexOf()或includes()方法来解决该问题。 使用indexOf()方法 indexOf()方法返回字符串中指定字符或字符串第一次出现的位置。返回值为-1表示未找到。可以通过以下方式使用它来判断一个字符串是否包含另一个字符串: let str = ‘h…

    JavaScript 2023年5月28日
    00
  • javascript学习笔记(十二) RegExp类型介绍

    下面是关于“javascript学习笔记(十二) RegExp类型介绍”的完整攻略。 RegExp类型介绍 RegExp类型是JS语言中表示正则表达式的类型。正则表达式是一种用于模式匹配的工具,可以用来匹配字符串中的文本模式,在字符串的搜索、替换、切割等操作中特别方便。 创建RegExp实例 创建RegExp实例的两种方式: 字面量方式 javascript…

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