返回

你所不知道的js数据储存与深复制(深拷贝)与浅复制(浅拷贝)

前端

JavaScript中变量的储存是通过栈内存和堆内存来完成的。栈内存主要用于储存基本数据类型的值,如数字、字符串和布尔值等。而堆内存则用于储存对象和数组等复杂的数据结构。当我们创建一个对象时,JavaScript会在堆内存中为该对象分配空间,并同时在栈内存中储存该对象的地址。因此,当我们修改对象时,实际上是修改了堆内存中储存的对象值,而栈内存中的地址值并不会改变。

在JavaScript中,对象复制有两种方式:浅复制和深复制。浅复制只复制对象本身,而不复制对象内部的属性。因此,如果我们修改了浅复制的对象,那么原对象也会受到影响。而深复制则会复制对象本身及其内部的所有属性,因此,如果我们修改了深复制的对象,原对象不会受到影响。

在JavaScript中,我们可以使用两种方式来实现浅复制:Object.assign()方法和展开运算符(...)。Object.assign()方法可以将一个对象的所有属性复制到另一个对象中,而展开运算符(...)可以将一个数组的所有元素复制到另一个数组中。

// 使用Object.assign()方法实现浅复制
const obj1 = {
  name: 'John Doe',
  age: 30
};

const obj2 = Object.assign({}, obj1);

// 修改obj2的name属性
obj2.name = 'Jane Doe';

// 输出obj1和obj2
console.log(obj1); // { name: 'John Doe', age: 30 }
console.log(obj2); // { name: 'Jane Doe', age: 30 }
// 使用展开运算符(...)实现浅复制
const arr1 = [1, 2, 3];

const arr2 = [...arr1];

// 修改arr2的第一个元素
arr2[0] = 4;

// 输出arr1和arr2
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [4, 2, 3]

在JavaScript中,我们可以使用两种方式来实现深复制:JSON.parse()方法和递归。JSON.parse()方法可以将一个JSON字符串解析成一个JavaScript对象,而递归则可以深度遍历一个对象,并复制该对象及其内部的所有属性。

// 使用JSON.parse()方法实现深复制
const obj1 = {
  name: 'John Doe',
  age: 30
};

const obj2 = JSON.parse(JSON.stringify(obj1));

// 修改obj2的name属性
obj2.name = 'Jane Doe';

// 输出obj1和obj2
console.log(obj1); // { name: 'John Doe', age: 30 }
console.log(obj2); // { name: 'Jane Doe', age: 30 }
// 使用递归实现深复制
const deepCopy = (obj) => {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  }

  const newObj = {};
  for (const key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
};

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

const obj2 = deepCopy(obj1);

// 修改obj2的name属性
obj2.name = 'Jane Doe';

// 修改obj2的address.street属性
obj2.address.street = '456 Elm Street';

// 输出obj1和obj2
console.log(obj1); 
/*
{
  name: 'John Doe',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
}
*/

console.log(obj2); 
/*
{
  name: 'Jane Doe',
  age: 30,
  address: {
    street: '456 Elm Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
}
*/