解构赋值:深拷贝还是浅拷贝

在JavaScript中,解构赋值是一项非常方便的操作。通过解构赋值,我们可以轻松地将数组或对象的成员值分配给变量。但是,使用解构赋值时,我们需要了解它所使用的是深拷贝还是浅拷贝的机制。在这篇文章中,我们将从多个方面详细阐述解构赋值的深拷贝和浅拷贝机制。

一、基础知识

  解构赋值是以“结构”为单位来进行赋值的操作。例如,我们可以使用数组或对象的键来将它们的值分配给变量,例如:

“`javascript
const arr = [1, 2, 3];
const [x, y, z] = arr;
console.log(x, y, z); // 1 2 3
“`
“`javascript
const obj = { foo: ‘hello’, bar: ‘world’ };
const {foo, bar} = obj;
console.log(foo, bar); // hello world
“`

  解构赋值的核心是绑定。它会把右侧的值绑定到左侧的变量上。

二、基本类型

  在解构赋值中,基本类型是属于浅拷贝的范畴。具体来说,如果我们使用解构赋值将一个基本类型数据赋给另一个变量,那么这两个变量将指向同一个内存地址。例如:

“`javascript
let a = ‘hello’;
let b = a; // 直接复制
console.log(a, b); // hello hello
a = ‘world’;
console.log(a, b); // world hello
“`

  在这个例子中,尽管我们改变了变量a的值,但变量b的值仍然是原始的“hello”值。这是因为基本类型的赋值时采用的是值传递,这种特性也被延续到了解构赋值中。

  可以用下面的代码对解构赋值的浅拷贝进行证明:

“`javascript
let a = { foo: ‘hello’ };
let b = { …a }; // 通过扩展运算符进行浅拷贝
console.log(a, b); // { foo: ‘hello’ } { foo: ‘hello’ }
a.foo = ‘world’;
console.log(a, b); // { foo: ‘world’ } { foo: ‘hello’ }
“`

  在这个例子中,我们使用了扩展运算符进行了一个表面上是完整拷贝的操作,但其实这里只是进行了浅拷贝。当我们修改变量a的属性foo时,变量b并没有跟着修改,因为两个变量只是引用了同一个对象的地址。

三、引用类型

  引用类型是指对象、数组和函数。当我们用解构赋值时,它们属于深拷贝范畴。例如:

“`javascript
let a = { foo: { bar: ‘hello’ } };
let b = { …a }; // 通过扩展运算符进行浅拷贝
console.log(a, b); // { foo: { bar: ‘hello’ } } { foo: { bar: ‘hello’ } }
a.foo.bar = ‘world’;
console.log(a, b); // { foo: { bar: ‘world’ } } { foo: { bar: ‘hello’ } }
“`

  尽管我们使用了扩展运算符进行了浅拷贝,但当我们修改了变量a的属性时,变量b的引用关系并没有改变。因此,在JavaScript中,解构赋值对引用类型的赋值采用的是深拷贝。

  同时我们可以使用Object.assign()或者JSON.parse()来进行深拷贝的复制操作。例如:

“`javascript
let a = { foo: { bar: ‘hello’ } };
let b = JSON.parse(JSON.stringify(a)); // 通过JSON来进行深拷贝复制
console.log(a, b); // { foo: { bar: ‘hello’ } } { foo: { bar: ‘hello’ } }
a.foo.bar = ‘world’;
console.log(a, b); // { foo: { bar: ‘world’ } } { foo: { bar: ‘hello’ } }
“`

  这里通过JSON来进行深拷贝复制,可以看出深度复制是完整的。修改变量a的属性foo的子属性bar时,变量b的值没有跟着改动。

四、函数参数

  在JavaScript中,我们经常将对象作为函数参数进行传递。使用解构赋值可以让代码更加简洁易读。例如:

“`javascript
function foo({ x = 1, y = 2 } = {}) {
console.log(x, y);
}
foo({ x: 3 }); // 3 2
foo(); // 1 2
“`

  在这个例子中,我们将解构赋值作为函数的默认参数进行传递。通过这样的方式,我们可以在函数中使用解构赋值,同时也可以不传递参数。

  需要注意的是,当我们使用默认参数时,如果没有传入参数,则会被默认赋值为undefined。这样,我们可以使用解构赋值的默认值机制来为变量提供一个默认值。例如:

“`javascript
function foo({ x = 1, y = 2 } = { x: 0, y: 0 }) {
console.log(x, y);
}
foo({ x: 3 }); // 3 2
foo(); // 1 2
“`

  在这个例子中,我们使用了解构赋值的默认参数,同时为传递参数的情况做了处理,使得其默认参数为x: 0, y: 0。

五、数组拼接

  在解构赋值中,我们可以使用剩余运算符来进行数组拼接。例如:

“`javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr = […arr1, …arr2];
console.log(arr); // [1, 2, 3, 4, 5, 6]
“`

  当我们使用剩余运算符时,它所代表的是数组中的其余元素。由于解构赋值会浅拷贝数组元素,因此我们使用剩余运算符进行数组拼接时,其实是在创建一个新的数组,而不是在原有的数组上进行操作。

六、小结

  在这篇文章中,我们从多个方面详细阐述了解构赋值的深拷贝和浅拷贝机制。我们了解了基础知识、基本类型、引用类型、函数参数、数组拼接等内容。通过这样的介绍,我们可以更好地使用解构赋值,同时避免在编写代码的时候出现意想不到的结果。

  代码示例:https://codepen.io/parkouroff/pen/ZELvwvK

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/181643.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-11-23 06:43
下一篇 2024-11-23 06:43

相关推荐

  • Python文件路径赋值

    Python中文件操作是非常基本的操作,而文件路径是文件操作的前提。本文将从多个方面阐述如何在Python中赋值文件路径。 一、绝对路径和相对路径 在Python中,路径可以分为绝…

    编程 2025-04-28
  • 如何使用Python将输出值赋值给List

    对标题进行精确、简明的解答:本文将从多个方面详细介绍Python如何将输出的值赋值给List。我们将分步骤进行探讨,以便读者更好地理解。 一、变量类型 在介绍如何将输出的值赋值给L…

    编程 2025-04-28
  • Python中赋值运算符和相等运算符解析

    Python是一种高级编程语言,它通常被用于开发 Web 应用程序、人工智能、数据分析和科学计算。在Python中,赋值运算符和相等运算符是非常常见和基本的运算符,它们也是进行编程…

    编程 2025-04-28
  • Python中赋值种类

    本篇文章将从多个方面对Python中赋值种类做详细的阐述,包括普通赋值、序列解包赋值、链式赋值、增量赋值和全局赋值。 一、普通赋值 普通赋值是Python中最基础的赋值操作,通过等…

    编程 2025-04-28
  • Python同步赋值语句的使用方法和注意事项

    Python同步赋值语句是Python中用来同时为多个变量赋值的一种方法。通过这种方式,可以很方便地同时为多个变量赋值,从而提高代码的可读性和编写效率。下面从多个方面详细介绍Pyt…

    编程 2025-04-28
  • Python用input赋值用法介绍

    本文将从多个方面详细阐述Python中如何使用input函数来赋值,以帮助读者更好的理解和应用该函数。 一、基础使用 1、input函数的作用是从键盘输入一行文本,并返回一个字符串…

    编程 2025-04-27
  • Python二维字典赋值

    Python中的字典是一种非常有用的数据结构,它允许开发人员将键值对存储在一起以便于访问和操作。除了普通的字典,Python还允许创建二维字典,它们是由键值对组成的键值对。这些二维…

    编程 2025-04-27
  • Python元组赋值给变量

    本文将详细阐述Python中元组赋值给变量的多个方面,包括元组的基本操作、元组赋值、交换变量、可变和不可变元组等内容。 一、元组基本操作 元组是Python中的一个重要数据类型,它…

    编程 2025-04-27
  • 解构赋值

    解构是ES6中的一个重要特性。解构赋值语法可以将一个数组或对象中的值提取到不同的变量中,使代码更加简洁易懂。这篇文章将从多个方面对js解构做详细的阐述,并给出对应的代码示例。 一、…

    编程 2025-04-23
  • vector初始化赋值详解

    一、基础概念 vector是一个封装了动态大小数组的顺序容器(Sequence Container)。与C-style数组不同,它能够根据需要自动扩展,它是连续存储的,与数组一样高…

    编程 2025-04-22

发表回复

登录后才能评论