Skip to content

JavaScript 深、浅拷贝

拷贝的目的(摘录)

shell
深浅拷贝都是针对于引用类型说的,拷贝便是复制,意思是在不改变原有对象数据的基础上再创建一个新的对象副本,然而又根据对象的层级深浅又有不同的拷贝方法,所以有了深浅拷贝的说法

什么是浅拷贝

浅拷贝只复制对象的第一层属性,如果第一次属性的值是引用类型(如对象、数组等),则复制的是引用而不是实际的对象。只适用属性为简单类型的对象

什么是深拷贝

深拷贝会递归复制对象的所有层级,创建一个完全独立的新对象,此法适合拷贝层级大于一级的对象类型数据

实现浅拷贝

shell
方式一:... 拓展运算符,可实现数组和对象的浅拷贝
方式二:对象的 Object.assign() 方法,可实现对象的浅拷贝
方式三:数组的 slice()、concat()、filter()、map() 方法,可实现数组浅拷贝

实现深拷贝

  1. 方式一:JSON.parse(JSON.stringify()) 方法,可实现数组和对象的深拷贝

缺点:此方式会忽略 undefined、Symbol、function,Date/Blob 等特殊结构;无法处理循环引用(会报错)。

  1. 方式二:手写循环递归
js
function deepClone(target) {
  if (typeof target === "object" && target !== null) {
    const result = Array.isArray(target) ? [] : {};
    for (let prop in target) {
      if (target.hasOwnProperty(prop)) {
        result[prop] = deepClone(target[prop]);
      }
    }
    return result;
  } else {
    return target;
  }
}
  1. 方式三:lodash 深拷贝
shell
_.cloneDeep()

总结

  1. 深浅拷贝是针对对象类型的数据来说的
  2. 使用场景差异,对于只有一层的简单对象直接使用浅拷贝即可,对于深层对象则需使用深拷贝
  3. 可以借助 lodash 实现深浅拷贝,比如 _.cloneDeep()

JS 深浅拷贝以及如何实现(另一稿)

JS 深浅拷贝

shell
# 拷贝的目的
深浅拷贝都是针对于引用类型说的,拷贝便是复制,意思是在不改变原有对象数据的基础上再创建一个新的对象副本,然而又根据对象的层级深浅又有不同的拷贝方法,所以有了深浅拷贝的说法

# 什么是深拷贝
深拷贝会递归复制对象的所有层级,创建一个完全独立的新对象,此法适合拷贝层级大于一级的对象类型数据

# 什么是浅拷贝
浅拷贝只复制对象的第一层属性,如果第一次属性的值是引用类型(如对象、数组等),则复制的是引用而不是实际的对象。所以浅拷贝只适用属性为简单类型的对象数据

实现深拷贝

shell
# 实现深拷贝常用方法
1. JSON.parse (JSON.stringify ())
此法最常用,但有局限性
无法拷贝 function、undefined、Symbol 类型的属性(会丢失);
无法拷贝循环引用的对象(会报错);
无法拷贝 Date、RegExp 等特殊对象(会转为字符串 / 空对象)。
所以此法只适合属性值是非undefined的基础类型数据,和值为对象和数组的数据

2. 手写递归深拷贝,没有局限性

3. lodash 库的 _.cloneDeep(),兼顾性能和兼容性

实现浅拷贝

shell
# 实现浅拷贝常用方法
方式一:... 拓展运算符,可实现数组和对象的浅拷贝
方式二:对象的 Object.assign() 方法,可实现对象的浅拷贝
方式三:数组的 slice()、concat()、filter()、map() 方法,可实现数组浅拷贝