JavaScript浅拷贝实现方式

前端2023-07-1226 人已阅来源:网络

在 JavaScript 开发中,我们经常需要处理对象或数组的拷贝操作。在实际开发中,常常会遇到浅拷贝的需求,即将一个对象或数组的内容复制到另一个对象或数组中,复制后的新对象或数组与原对象或数组共享一部分数据。本文将介绍 JavaScript 中浅拷贝的实现方式。

一、什么是浅拷贝?

在 JavaScript 中,对象和数组都是引用类型,当我们将一个对象或数组赋值给一个新的变量时,实际上是将原对象或数组的引用赋值给了新变量。

例如,以下代码将一个对象赋值给一个新变量:

let obj1 = { name: '张三', age: 18 };
let obj2 = obj1;

在这个例子中,obj2obj1 并不是两个不同的对象,而是指向同一个内存地址的两个引用。

在实际开发中,我们可能需要将一个对象或数组的内容复制到另一个对象或数组中,这时就需要进行浅拷贝。

浅拷贝是指仅复制对象或数组的第一层数据结构,如果对象或数组中还包含对象或数组,复制后的新对象或数组与原对象或数组将共享这些引用类型的数据结构,如下图所示:

浅拷贝示例

如图所示,对象 A 包含两个属性 a 和 b,属性 b 的值为一个对象 B,对象 B 又包含两个属性 c 和 d。当对对象 A 进行浅拷贝后,生成一个新的对象 C,对象 C 与对象 A 共享属性 a 和 b,即浅拷贝只复制了对象 A 的第一层结构,而对象 B 只是被引用了一次,对象 C 与对象 A 共享对象 B,即两个对象的地址相同。

二、浅拷贝实现方式

下面将介绍 JavaScript 中几种常见的浅拷贝实现方式。

  1. 手动遍历

手动遍历对象或数组,将每个属性或元素复制到新的对象或数组中。这种方式简单易懂,代码可读性高,但对于嵌套层次较多的对象或数组,代码量将会很大。

function shallowCopy(obj) {
  if (Array.isArray(obj)) {
    return obj.slice();
  } else if (typeof obj === 'object' && obj !== null) {
    let newObj = {};
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        newObj[key] = obj[key];
      }
    }
    return newObj;
  } else {
    return obj;
  }
}

在这个例子中,我们首先判断待拷贝的对象是数组还是对象。如果是数组,我们使用 slice() 方法进行浅拷贝;如果是对象,我们通过循环遍历对象的属性,并将每个属性复制到新对象中,最后返回新对象。

  1. Object.assign()

Object.assign() 方法用于将一个或多个对象的属性复制到目标对象中,如果多个对象具有相同的属性,则后续对象中的属性将覆盖先前对象中的属性。Object.assign() 方法只会复制对象的第一层数据结构,如果对象中包含引用类型的属性,则新对象与原对象将共享这些引用类型的属性。

let obj1 = { name: '张三', age: 18, hobbies: ['coding', 'reading'] };
let obj2 = Object.assign({}, obj1);

在这个例子中,我们使用 Object.assign() 方法将对象 obj1 复制到一个新的空对象中,生成一个新的对象 obj2。

注意,使用 Object.assign() 方法时,第一个参数必须是目标对象,后面的参数是源对象,如果源对象具有相同的属性,则后续对象中的属性将覆盖先前对象中的属性。如果源对象中有属性是引用类型,那么复制后的新对象将与原对象共享这些属性。

  1. 扩展运算符

扩展运算符(spread operator)是 ES6 中新增的语法,可以用于展开数组或对象,将它们的内容复制到另一个数组或对象中。扩展运算符只能用于对象或数组的第一层数据结构,如果对象或数组中包含引用类型的属性,则新对象或数组与原对象或数组将共享这些属性。

let arr1 = [1, 2, 3];
let arr2 = [...arr1];

let obj1 = { name: '张三', age: 18, hobbies: ['coding', 'reading'] };
let obj2 = { ...obj1 };

在这个例子中,我们使用扩展运算符将数组 arr1 和对象 obj1 的内容复制到新的数组和对象中,生成新的数组 arr2 和对象 obj2。

扩展运算符使用起来方便简洁,代码可读性高,但对于嵌套层次较多的对象或数组,代码量还是比较大。

  1. Array.from()

Array.from() 方法用于将一个类数组对象或可迭代对象转换成一个新的数组,可以用于数组的浅拷贝。

let arr1 = [1, 2, 3];
let arr2 = Array.from(arr1);

在这个例子中,我们使用 Array.from() 方法将数组 arr1 转换成一个新的数组 arr2,实现了浅拷贝。

需要注意的是,Array.from() 方法只能用于类数组对象或可迭代对象的浅拷贝,如果需要对对象进行浅拷贝,还需要使用其他方法。

三、总结

本文介绍了 JavaScript 中浅拷贝的实现方式,包括手动遍历、Object.assign() 方法、扩展运算符和 Array.from() 方法。实际开发中,我们可以根据实际需要选择最适合的一种方式进行浅拷贝操作。需要注意的是,浅拷贝只是复制了对象或数组的第一层数据结构,如果对象或数组中包含引用类型的属性,则浅拷贝复制后的新对象或数组与原对象或数组将共享这些属性。如果需要实现深拷贝,则需要使用其他方法进行操作。

以上就是JavaScript浅拷贝实现方式的详细内容!