返回

深入浅出,剖析js值类型引用类型及深浅拷贝

前端

JavaScript中的值类型与引用类型

JavaScript中,变量可以存储两种类型的数据:值类型和引用类型。

值类型
值类型存储实际值,每个值类型变量都存储自己的值,它们彼此独立。常见的JavaScript值类型包括:

  • 数字(如:1、3.14、-5)
  • 字符串(如:'hello'、"world")
  • 布尔值(如:true、false)
  • undefined
  • null

引用类型
引用类型存储指向另一个值的指针,而不是实际值。引用类型变量存储的指针指向堆内存中的对象,而这些对象包含实际值。常见的JavaScript引用类型包括:

  • 对象(如:{name: 'John Doe', age: 30})
  • 数组(如:[1, 2, 3, 4, 5])
  • 函数(如:function myFunction() { ... })

深浅拷贝与浅拷贝

当将一个引用类型变量的值赋给另一个引用类型变量时,可以进行深拷贝或浅拷贝。

深拷贝
深拷贝会复制对象及其所有属性的值,创建一个完全独立的新对象。即使原始对象或其属性发生变化,新对象的值也不会受到影响。

const obj1 = {
  name: 'John Doe',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

const obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝

obj2.name = 'Jane Doe';
obj2.address.street = '456 Elm Street';

console.log(obj1); // { name: 'John Doe', age: 30, address: { ... } }
console.log(obj2); // { name: 'Jane Doe', age: 30, address: { ... } }

浅拷贝
浅拷贝只复制对象及其所有属性的引用,而不是实际值。如果原始对象或其属性发生变化,新对象的值也会受到影响。

const obj1 = {
  name: 'John Doe',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

const obj2 = obj1; // 浅拷贝

obj2.name = 'Jane Doe';
obj2.address.street = '456 Elm Street';

console.log(obj1); // { name: 'Jane Doe', age: 30, address: { ... } }
console.log(obj2); // { name: 'Jane Doe', age: 30, address: { ... } }

何时使用深拷贝或浅拷贝

在JavaScript中,深拷贝和浅拷贝都各有其用途。

深拷贝 适用于以下场景:

  • 需要创建一个完全独立的对象,不会受到原始对象或其属性变化的影响。
  • 需要将对象传递给另一个函数或模块,并确保该函数或模块不会改变原始对象。
  • 需要将对象存储在持久性存储中(如数据库或文件系统),并确保该对象在检索时不会发生变化。

浅拷贝 适用于以下场景:

  • 需要创建另一个对象,但不需要完全独立。
  • 需要将对象传递给另一个函数或模块,并且允许该函数或模块改变原始对象。
  • 需要在内存中临时存储对象,并且不需要持久性存储。

结论

在本文中,我们介绍了JavaScript中的值类型和引用类型,以及深拷贝和浅拷贝的区别和联系。我们还讨论了何时使用深拷贝或浅拷贝。希望这些知识能够帮助你写出更健壮可靠的JavaScript代码。