返回

手撕JS,一分钟读懂浅复制与深复制

前端

浅尝辄止,初识浅拷贝

想象一个存钱罐,里面装满了硬币。如果我们想取钱,我们可以直接拿出一枚硬币,这就是浅拷贝 。它只复制了硬币的表面值,而不会深入到它的内部结构。

同理,在计算机编程中,浅拷贝只复制了对象的属性值,而不会深入到子属性或嵌套对象。举个例子:

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

const obj2 = {...obj};

如果我们修改obj2中的address属性,它不会影响到obj中的address属性,因为浅拷贝只复制了引用,而不是实际值。

深入骨髓,探究深拷贝

深拷贝就像把存钱罐整个倒出来,数清每一枚硬币。它会递归地复制对象的每个属性,直到遇到基本数据类型。

可以使用JSON.stringify()JSON.parse()函数来实现深拷贝:

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

const obj3 = JSON.parse(JSON.stringify(obj));

现在修改obj3中的address属性不会影响obj,因为它们是完全独立的两个对象。

剖析利刃,eval函数的妙用

eval函数像一把利刃,可以斩断对象的关联。它可以将一个JSON字符串转换成一个新的对象,这个对象与原始对象完全无关:

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

const obj4 = eval('(' + JSON.stringify(obj) + ')');

箭无虚发,箭头函数的优势

箭头函数是函数表达式的精简版。它们没有自己的this,因此在处理对象方法时要小心:

const obj = {
  name: 'John Doe',
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  },
  greet: () => {
    console.log(`Hello, my name is ${this.name}.`);
  }
};

在这个例子中,greet()方法无法访问对象的name属性,因为箭头函数的this指向全局作用域。

常见问题解答

  1. 浅拷贝和深拷贝的区别是什么?

浅拷贝只复制对象的属性值,而深拷贝会递归地复制对象的每个属性。

  1. 什么时候应该使用浅拷贝?

当不需要修改嵌套对象或子属性的值时,可以考虑使用浅拷贝。

  1. 什么时候应该使用深拷贝?

当需要完全独立的对象副本时,应该使用深拷贝,以避免修改原始对象。

  1. 如何实现深拷贝?

可以使用JSON.stringify()JSON.parse()函数、eval函数或使用第三方库。

  1. 箭头函数在深拷贝中的作用是什么?

箭头函数可以用来创建不会修改原始对象的方法。