前端使用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)
上一篇 2天前
下一篇 2天前

相关文章

  • JavaScript中调用函数的4种方式代码实例

    让我来详细讲解一下“JavaScript中调用函数的4种方式代码实例”。 1. 直接调用函数 直接调用函数指的是使用函数名,后跟一对圆括号,不带任何修饰符或执行环境调用函数。 示例: function sayHello() { console.log("Hello!"); } sayHello(); 上述示例中我们定义了一个函数 sayH…

    JavaScript 2天前
    00
  • JavaScript基础之静态方法和实例方法分析

    JavaScript基础之静态方法和实例方法分析 什么是静态方法与实例方法? 在 JavaScript 中,我们常常需要使用到一些函数或方法来将数据进行处理或者实现某些功能。那么,这些函数或方法又可以分为两种不同类型:静态方法和实例方法。 静态方法:静态方法是指在类名上被调用,而无需实例化对象的方法。它们通常用于创建和管理类本身和类内部属性,如Math.ab…

    JavaScript 1天前
    00
  • 用javascript实现倒计时效果

    下面给出实现倒计时效果的完整攻略。 标题 用JavaScript实现倒计时效果 步骤 1. 获取倒计时目标时间 要实现倒计时效果,首先需要获取倒计时的目标时间。这里我们可以利用JavaScript内置的Date对象来获取目标时间。 const targetTime = new Date(‘2021-10-15T18:00:00Z’).getTime(); /…

    JavaScript 2天前
    00
  • JavaScript实现汉字转换为拼音及缩写的方法示例

    针对JavaScript实现汉字转换为拼音及缩写的方法,我将详细讲解以下的攻略: 准备工作 在实现汉字转拼音及缩写之前,我们需要先下载一个JavaScript拼音库,常用的库有pinyin和pinyin-engine。下面以pinyin库为例,讲述如何使用。 步骤如下: 在html中引入pinyin.js库: “`html “` 安装pinyin库: 在…

    JavaScript 2023年5月19日
    00
  • js中slice()方法的使用说明

    JS中slice()方法的使用说明 概述 在JavaScript中,slice()方法可以对字符串和数组进行截取操作,并返回一个新的字符串或数组。slice()方法接受两个参数,分别为起始位置和结束位置,如果不传入结束位置,则默认截取到字符串或数组的末尾。需要注意的是,slice()方法并不会修改原来的字符串或数组,而是返回截取后的新字符串或数组。 语法 字…

    JavaScript 2天前
    00
  • 浅谈(0,eval)(‘window’)

    浅谈(0,eval)(‘window’) 最近研究qiankun 源码,在import-html-entry 包中看到这个,一脸懵,研究了一下,记录一下。参考了这篇博客 这个干啥用的 // 通过这种方式获取全局 window,因为 script 也是在全局作用域下运行的,所以我们通过 window.proxy 绑定时也必须确保绑定到全局 window 上 /…

    JavaScript 2023年5月6日
    00
  • 浅谈 Webpack 如何处理图片(开发、打包、优化)

    浅谈 Webpack 如何处理图片(开发、打包、优化) 在Web开发中,图片作为Web页面重要的组成部分,在Webpack中如何处理图片是一个必须要掌握的技能。常见的处理方式包括以下几种: 1. 在代码中使用 import 或 require 导入图片 Webpack支持将图片(包括PNG、JPG、GIF、SVG等格式)作为模块来处理,并通过模块化的方式导入…

    JavaScript 2023年5月19日
    00
  • javascript正则表达式简介

    JavaScript正则表达式简介 JavaScript中的正则表达式是指一种用于匹配和操作字符串的表达式。它们被广泛用于文本搜索和替换操作中。在JavaScript中,使用RegExp对象来表示正则表达式。 正则表达式语法 正则表达式由字符和特殊字符组成,在此先介绍一些基本的概念: 字符表达式:由字母、数字、特殊字符等组成的一个或多个字符。 特殊字符:表达…

    JavaScript 2023年5月19日
    00
  • JS对URL字符串进行编码/解码分析

    好的!JS对URL字符串进行编码/解码的主要方法有两种:encodeURIComponent和decodeURIComponent。下面对它们进行详细说明: encodeURIComponent encodeURIComponent 方法可以将字符串中的非字母数字字符(比如空格、中文、特殊符号)转换为十六进制字符。转换后的字符前面加上 %,这样可以在URL中…

    JavaScript 2023年5月20日
    00
  • JSONP解决JS跨域问题的实现

    让我们来详细讲解一下如何使用JSONP来解决JS跨域问题。 什么是JSONP JSONP是一种跨域方式,全称为JSON with Padding。它通过动态创建script标签的方式,将请求的数据包装在函数中返回,并执行这个函数,从而实现跨域请求数据的目的。 JSONP的原理很简单,就是利用script标签的src属性可以跨域请求资源,而服务端返回的是一个具…

    JavaScript 2天前
    00