JavaScript深拷贝与浅拷贝实现详解

JavaScript深拷贝与浅拷贝实现详解

什么是拷贝?

在JavaScript中,我们经常需要将对象或者数组进行复制操作,这被称为拷贝。在拷贝过程中,我们需要注意两个概念:浅拷贝和深拷贝。

什么是浅拷贝?

浅拷贝仅仅是复制了对象或数组的引用,而并没有克隆对象或数组。也就是说,对于被拷贝的对象或数组,它们的属性仍然指向原对象或数组中的属性。浅拷贝通常使用的方法有:

Object.assign方法

const obj = {a: 1, b: 2};
const copy = Object.assign({}, obj);
console.log(copy); // {a: 1, b: 2}

扩展运算符(...)

const obj = {a: 1, b: 2};
const copy = {...obj};
console.log(copy); // {a: 1, b: 2}

需要注意的是,浅拷贝只能复制对象或数组的一层属性,如果被拷贝的对象或数组中还有嵌套的对象或数组,浅拷贝并不会进行递归拷贝。

什么是深拷贝?

深拷贝则是完全复制了对象或数组,包括对象或数组中的所有嵌套对象或数组,新的对象或数组和原对象或数组完全独立无关。深拷贝通常使用的方法有:

JSON.parse和JSON.stringify方法

const obj = {a: 1, b: {c: 2}};
const copy = JSON.parse(JSON.stringify(obj));
console.log(copy); // {a: 1, b: {c: 2}}

需要注意的是,因为JSON.stringify方法无法处理Symbol、Date、函数等特殊类型,因此在深拷贝过程中这些类型会被忽略掉。

递归拷贝

function deepCopy(obj) {
  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  } else if (typeof obj === 'object' && obj !== null) {
    const copy = {};
    Object.keys(obj).forEach((key) => {
      copy[key] = deepCopy(obj[key]);
    });
    return copy;
  } else {
    return obj;
  }
}

const obj = {a: 1, b: {c: 2}};
const copy = deepCopy(obj);
console.log(copy); // {a: 1, b: {c: 2}}

递归拷贝可以完美地复制对象或数组中的所有属性,除了Symbol、Date、函数等特殊类型。

示例说明

示例一

const obj = {
  a: 1,
  b: {
    c: 2
  }
};
const copy1 = Object.assign({}, obj);
const copy2 = {...obj};
const copy3 = JSON.parse(JSON.stringify(obj));
const copy4 = deepCopy(obj);

obj.b.c = 3;

console.log(copy1); // {a: 1, b: {c: 3}}
console.log(copy2); // {a: 1, b: {c: 3}}
console.log(copy3); // {a: 1, b: {c: 2}}
console.log(copy4); // {a: 1, b: {c: 2}}

在这个示例中,我们首先定义了一个对象obj,其中包含一个嵌套对象b。然后我们使用了四种方法分别对obj进行了浅拷贝和深拷贝。接着,我们修改了obj.b.c的值为3,然后输出了四个拷贝的结果。可以看到,浅拷贝的两种方法都会随着原对象的改变而发生改变,而深拷贝的两种方法则不受原对象的影响。

示例二

const arr = [1, 2, [3, 4]];
const copy1 = arr.slice();
const copy2 = [...arr];
const copy3 = JSON.parse(JSON.stringify(arr));
const copy4 = deepCopy(arr);

arr[2][0] = 5;

console.log(copy1); // [1, 2, [5, 4]]
console.log(copy2); // [1, 2, [5, 4]]
console.log(copy3); // [1, 2, [3, 4]]
console.log(copy4); // [1, 2, [3, 4]]

在这个示例中,我们首先定义了一个数组arr,其中包含一个嵌套数组。然后我们使用了四种方法分别对arr进行了浅拷贝和深拷贝。接着,我们修改了arr[2][0]的值为5,然后输出了四个拷贝的结果。可以看到,浅拷贝的两种方法都会随着原数组的改变而发生改变,而深拷贝的两种方法则不受原数组的影响。

总结

浅拷贝和深拷贝是JavaScript中常用的拷贝方式,每种方式都有其优缺点。在实际应用中,我们需要根据具体的情况选择合适的拷贝方式,以保证拷贝的结果符合预期。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript深拷贝与浅拷贝实现详解 - Python技术站

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

相关文章

  • js分解url参数(面向对象-极简主义法应用)

    下面是关于“js分解url参数(面向对象-极简主义法应用)”的完整攻略。 1.什么是URL参数 URL参数是指在URL中传递的键值对,以“&”符号分隔。例如以下URL中的参数是name=Lucy和age=18 http://www.example.com?name=Lucy&age=18 2.为什么要分解URL参数 在Web应用程序中,处理U…

    JavaScript 2023年5月19日
    00
  • Angular.js中window.onload(),$(document).ready()的写法浅析

    Angular.js在页面加载和渲染完成后,可以使用一些方法来操作DOM元素,例如window.onload()和$(document).ready()。但是在Angular.js中,推荐使用指令来操作DOM元素。本文将分别对window.onload()和$(document).ready()以及指令的使用进行讲解。 window.onload()的用法 …

    JavaScript 2023年6月10日
    00
  • js小数计算小数点后显示多位小数的实现方法

    下面是讲解“js小数计算小数点后显示多位小数的实现方法”的完整攻略。 实现方法 在JavaScript中,我们可以使用 toFixed() 方法来实现小数点后显示多位小数的功能。该方法可以接受一个整数参数,该参数表示我们想要保留的小数位数。当我们没有传递这个参数时,默认保留0位小数。 简单示例 下面是一个简单的示例。我们将两个小数相加,并且保留2位小数。 c…

    JavaScript 2023年6月11日
    00
  • 让JavaScript拥有类似Lambda表达式编程能力的方法

    要让JavaScript拥有类似Lambda表达式编程能力,可以使用箭头函数(Arrow Function)来实现。 箭头函数是ES6中新增的语法,简单来说就是一种更加简洁的函数表达式。通过箭头函数,我们可以更加简单快速地编写函数,并且可以方便地使用函数式编程的一些特性。 下面是箭头函数的基本语法: (argument1, argument2, …) =…

    JavaScript 2023年5月28日
    00
  • this[] 指的是什么内容 讨论

    关于”this[]”指的是什么,我们需要从以下几个方面来讨论: this关键字的含义和用法; 在使用this关键字时,this[]的含义与用法; 两个示例说明。 1. this关键字的含义和用法 在面向对象编程中,this关键字代表当前对象的引用。当我们在类的方法中使用this关键字时,代表这个类的当前对象。可以用来引用当前对象的属性和方法,也可以用来调用当…

    JavaScript 2023年6月11日
    00
  • js中关于Blob对象的介绍与使用

    什么是 Blob 对象 Blob 对象是 JavaScript 中的一个标准对象,它代表了一段二进制数据。通常我们会用它来存储二进制文件,比如图片、视频、音频等等。 在 JavaScript 中,我们可以使用 Blob 构造函数来创建一个 Blob 对象。它接受一个数组作为参数,数组元素可以是字符串、 ArrayBuffer 对象(用于表示二进制数据) 或 …

    JavaScript 2023年5月27日
    00
  • javascript 面向对象编程 function是方法(函数)

    当我们用JavaScript进行面向对象编程时,我们通常会使用对象和方法。对象是一个具有属性和方法的实体,而方法则是定义在对象中的函数。 在JavaScript中,通过使用构造函数和原型来创建对象和方法。构造函数是一个特殊的函数,它用于创建一个新的对象,而原型则用于定义对象的方法和属性。让我们来看一下一个简单的例子: // 创建构造函数 function P…

    JavaScript 2023年5月27日
    00
  • chrome浏览器如何断点调试异步加载的JS

    要断点调试异步加载的JS,需要使用Chrome浏览器的开发者工具。下面是详细的步骤: 打开网页,按F12调出开发者工具。 在开发者工具中,点击Sources(或快捷键Ctrl + Shift + S)。 在Sources面板里,选择要调试的JS文件并打开。 在JS文件中找到要调试的代码行,点击行号可以在该行设置断点。 在代码中使用debugger语句,同样可…

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