带你读《现代Javascript高级教程》十七、JavaScript深拷贝与浅拷贝(1)

简介: 带你读《现代Javascript高级教程》十七、JavaScript深拷贝与浅拷贝(1)

十七、JavaScript深拷贝与浅拷贝

引言

在JavaScript中,对象的拷贝是一项常见的操作。浅拷贝和深拷贝是两种常用的拷贝方式。浅拷贝只复制对象的引用,而深拷贝创建了一个全新的对象,包含与原始对象相同的值和结构。深拷贝和浅拷贝各有适用的场景和注意事项。

 

本文将详细介绍如何实现一个完整而优雅的深拷贝函数,处理循环引用和特殊类型,优化性能,并探讨深拷贝和浅拷贝的应用场景、注意事项和相关属性。

1. 深拷贝的实现

实现一个完整而优雅的深拷贝函数需要考虑以下几个方面:

1) 基本类型和特殊类型的处理

在实现深拷贝函数时,首先需要处理基本类型(如字符串、数字、布尔值等)和特殊类型(如函数、正则表达式和日期对象等)。对于基本类型,直接返回其值即可。对于特殊类型,可以选择直接引用原始对象,而不进行复制。

 

function deepClone(obj) {
  // 处理基本类型
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }
  // 处理特殊类型
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  if (obj instanceof Date) {
    return new Date(obj.getTime());
  }
  if (obj instanceof Function) {
    return obj;
  }
  // 处理普通对象和数组
  const clone = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;}

 

在上述代码中,我们使用 typeof 操作符判断基本类型,根据对象的类型选择适当的处理方式。对于函数、正则表达式和日期对象,我们使用相应的构造函数创建新的实例。

2) 处理循环引用

循环引用是指对象属性之间存在相互引用的情况,导致递归复制陷入无限循环。为了处理循环引用,我们可以使用一个额外的数据结构(如 Map WeakMap)来存储已经复制的对象,以便在遇到循环引用时进行判断和处理。

 

下面是一个修改后的 deepClone 函数,解决了循环引用问题:

function deepClone(obj, map = new Map()) {
  if (typeof obj !== 'object' || obj
 === null) {
    return obj;
  }
  if (map.has(obj)) {
    return map.get(obj);
  }
  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key], map);
    }
  }
  return clone;}

 

在上述代码中,我们使用 Map 数据结构来存储已经复制的对象。在每次递归调用时,我们首先检查 map 中是否存在当前对象的引用,如果存在则直接返回对应的副本。这样,我们可以避免陷入无限循环。


带你读《现代Javascript高级教程》十七、JavaScript深拷贝与浅拷贝(2)https://developer.aliyun.com/article/1349577?groupCode=tech_library

相关文章
|
2月前
|
JavaScript
vue中使用 HotKeys.js 教程(按键响应、快捷键开发)
vue中使用 HotKeys.js 教程(按键响应、快捷键开发)
144 0
|
3天前
|
JSON JavaScript 数据格式
手写JS实现深拷贝函数
本文介绍了如何实现一个深拷贝函数`deepClone`,该函数可以处理对象和数组的深拷贝,确保拷贝后的对象与原始对象在内存中互不干扰。通过递归处理对象的键值对和数组的元素,实现了深度复制,同时保留了函数类型的值和基础类型的值。
11 3
|
1月前
|
JavaScript NoSQL 前端开发
|
1月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
35 2
|
1月前
|
JavaScript 前端开发
JavaScript中的深拷贝和浅拷贝的实现讲解
在JavaScript中,浅拷贝与深拷贝用于复制对象。浅拷贝仅复制基本类型属性,对于引用类型仅复制引用,导致双方共享同一数据,一方修改会影响另一方。深拷贝则完全复制所有层级的数据,包括引用类型,确保双方独立。浅拷贝可通过简单属性赋值实现,而深拷贝需递归复制各层属性以避免共享数据。
37 1
|
1月前
|
JavaScript 前端开发
js中浅拷贝和深拷贝的区别
js中浅拷贝和深拷贝的区别
23 0
|
1月前
|
JavaScript 前端开发
js中浅拷贝,深拷贝的实现
js中浅拷贝,深拷贝的实现
27 0
|
1月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码
|
2月前
|
JSON JavaScript 数据格式
vue 绘制波形图 wavesurfer.js (音频/视频) 【实用教程】
vue 绘制波形图 wavesurfer.js (音频/视频) 【实用教程】
297 3
|
2月前
|
存储 JavaScript 前端开发
js【详解】数据类型原理(含变量赋值详解-浅拷贝)
js【详解】数据类型原理(含变量赋值详解-浅拷贝)
30 0