详细聊聊JS中不一样的深拷贝

下面我将详细讲解JS中不一样的深拷贝的完整攻略。

什么是深拷贝

深拷贝是指将一个对象完整复制一份并生成一个新对象,新对象和旧对象互不影响,即使新对象被修改了,旧对象也不会发生改变。

JavaScript 中的深拷贝

在 JavaScript 中,拷贝对象的方法是 Object.assign() 或者使用扩展运算符 ...。然而,这些拷贝方法都只能进行浅拷贝。

浅拷贝只是复制了对象的第一层级属性,如果是一个嵌套的对象就会出现问题。比如一个对象的属性值是一个引用类型,那么浅拷贝会复制这个引用类型的内存地址,新旧对象的这一属性的值就会指向同一个内存地址。

因此,如果要进行深拷贝,需要使用其他方法或者手动实现深拷贝的方法。下面介绍两种比较常见的深拷贝方式。

JSON.parse(JSON.stringify(obj))

使用 JSON.parse(JSON.stringify(obj)) 可以实现深拷贝。它的原理是利用 JSON.stringify() 将原对象序列化成一个 JSON 字符串,再利用 JSON.parse() 将这个 JSON 字符串解析成一个新的对象,这个新的对象与原对象没有任何的引用关系。

但是,这个方法是有限制的,它只能序列化那些 JSON 能够表示的数据类型,而不能序列化那些不能被表示为 JSON 的数据类型,比如 undefined 和 function。

代码示例:

function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj))
}

let oldObj = {name: '张三', age: 18, info: {hobby: 'basketball'}}
let newObj = deepCopy(oldObj)

console.log(oldObj.age)    // 18
console.log(newObj.age)    // 18

oldObj.age = 20
console.log(oldObj.age)    // 20
console.log(newObj.age)    // 18

oldObj.info.hobby = 'football'
console.log(oldObj.info.hobby)    // football
console.log(newObj.info.hobby)    // basketball

可以看到,使用这种方式进行深拷贝,无法复制原始对象中的引用类型,修改原始对象的引用类型会影响复制后的引用类型。

递归实现

另外一种方法是手动实现递归拷贝,递归遍历对象,复制对象的每一个属性,直到遍历到属性值为基本类型时结束递归。

代码示例:

function deepCopy(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  let newObj = Array.isArray(obj) ? [] : {}

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopy(obj[key])
    }
  }

  return newObj
}

let oldObj = {name: '张三', age: 18, info: {hobby: 'basketball'}}
let newObj = deepCopy(oldObj)

console.log(oldObj.age)    // 18
console.log(newObj.age)    // 18

oldObj.age = 20
console.log(oldObj.age)    // 20
console.log(newObj.age)    // 18

oldObj.info.hobby = 'football'
console.log(oldObj.info.hobby)    // football
console.log(newObj.info.hobby)    // basketball

可以看到,使用递归实现深拷贝,能够完整复制原始对象中的引用类型,修改原始对象的引用类型不会影响复制后的引用类型。

总结

以上两种方法都可以实现深拷贝,但是第一种方法是将原始对象序列化成字符串,然后又通过解析字符串生成一个新的对象,可能会带来额外的性能开销。而第二种方法是完全手写,需要自己实现递归遍历,并创建新的对象,相对而言比较繁琐。需要根据自己的实际业务需求选择适合的深拷贝实现方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详细聊聊JS中不一样的深拷贝 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • javascript常用的正则表达式实例

    以下是关于JavaScript常用的正则表达式实例的攻略。 正则表达式的基础知识 正则表达式是一种用于匹配字符串的方法,它基于一些规则来描述匹配模式。在JavaScript中,你可以用正则表达式去匹配一个字符串或者一个字符串数组。 在编写JavaScript中的正则表达式时,你需要使用RegExp对象。这个对象既可以通过字面量语法来创建,也可以从构造函数中实…

    JavaScript 2023年6月10日
    00
  • JavaScript实现可终止轮询请求的方法

    我将为您详细讲解“JavaScript实现可终止轮询请求的方法”的完整攻略。 1. 什么是轮询请求 轮询请求是指客户端通过一定的时间间隔周期性地向服务器发送请求,以获取最新的数据或状态。一般来说,客户端需要不断向服务器发送请求,直到服务端返回需要的最新信息。 2. 实现可终止轮询请求的方法 2.1 XMLHttpRequest XMLHttpRequest是…

    JavaScript 2023年6月11日
    00
  • javascript的基础知识(随缘更新)

    1.声明与变量 let声明的变量可以多次赋值 let 变量名 = 值; const修饰叫常量,只能赋值一次,但是引用的值可以改变 var声明的变量可以多次赋值 结论:能用let不用var ,因为作用域的问题 2.基本类型和对象类型 undefined 和 null undefined 指 未定义的对象或者属性时 ,或声明了变量没有赋初始值时 null 指不引…

    JavaScript 2023年4月18日
    00
  • JavaScript函数定义方法实例详解

    JavaScript函数定义方法实例详解 在JavaScript中,函数是一种重要的编程概念。函数能够帮助我们将代码组织得更好、复用性更高,并且能够进一步实现更为复杂的功能。下面将详细讲解JavaScript函数定义的多种方法。 1.函数声明 函数声明是一种最经典的JavaScript函数定义方式。 function add(a, b) { return a…

    JavaScript 2023年6月10日
    00
  • 浅谈javascript中onbeforeunload与onunload事件

    当用户即将关闭页面或者离开当前页面时,JavaScript中提供了两个常见的事件:onbeforeunload和onunload。 onbeforeunload事件 onbeforeunload事件会在页面关闭或者刷新之前触发,它可以用来提示用户保存数据或者进行其他的操作。这个事件触发后,浏览器会弹出一个确认对话框,询问用户是否确定要离开当前页面。 以下是o…

    JavaScript 2023年6月11日
    00
  • Three.js+React制作3D梦中海岛效果

    下面我将详细讲解“Three.js+React制作3D梦中海岛效果”的完整攻略。 简介 Three.js是一款JavaScript 3D库,它可以为我们简化3D场景的创建和管理。React是一款流行的JavaScript库,它可以让我们更容易地构建用户界面。将这两个库结合起来,我们可以更加高效的创建3D界面。 在本攻略中,我们将使用Three.js和Reac…

    JavaScript 2023年6月10日
    00
  • js console.log打印对象时属性缺失的解决方法

    当我们在JavaScript中使用console.log打印一个对象时,可能会发现某些属性没有被打印出来。这通常是由于对象里的属性只有在我们需要访问它们时才被计算出来,或者是因为它们被标记为不可枚举的。以下是解决这个问题的两个方法: 方法一:使用JSON.stringify JSON.stringify可以将对象解析成一个字符串,包括不可枚举属性,因此我们可…

    JavaScript 2023年5月28日
    00
  • 如何使用Bootstrap创建表单

    当使用Bootstrap创建表单时,可以利用Bootstrap提供的现成的组件和样式来快速搭建一个美观、易用、响应式的表单。 创建Bootstrap表单的步骤 引入Bootstrap的CSS和JS库文件。可以直接从官网下载(http://getbootstrap.com/),或者通过CDN引入。 <!– Bootstrap CSS –> &l…

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