带你读《现代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

相关文章
|
30天前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
43 4
|
1月前
|
JavaScript 前端开发
js教程——函数
js教程——函数
26 4
|
2月前
|
JSON JavaScript 数据格式
手写JS实现深拷贝函数
本文介绍了如何实现一个深拷贝函数`deepClone`,该函数可以处理对象和数组的深拷贝,确保拷贝后的对象与原始对象在内存中互不干扰。通过递归处理对象的键值对和数组的元素,实现了深度复制,同时保留了函数类型的值和基础类型的值。
22 3
|
1月前
|
JavaScript 前端开发 Java
Node.js 教程
10月更文挑战第1天
38 0
|
3月前
|
JavaScript NoSQL 前端开发
|
3月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
40 2
|
3月前
|
JavaScript 前端开发
JavaScript中的深拷贝和浅拷贝的实现讲解
在JavaScript中,浅拷贝与深拷贝用于复制对象。浅拷贝仅复制基本类型属性,对于引用类型仅复制引用,导致双方共享同一数据,一方修改会影响另一方。深拷贝则完全复制所有层级的数据,包括引用类型,确保双方独立。浅拷贝可通过简单属性赋值实现,而深拷贝需递归复制各层属性以避免共享数据。
62 1
|
3月前
|
JavaScript 前端开发
js中浅拷贝和深拷贝的区别
js中浅拷贝和深拷贝的区别
28 0
|
3月前
|
JavaScript 前端开发
js中浅拷贝,深拷贝的实现
js中浅拷贝,深拷贝的实现
33 0
|
3月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码