你不容错过的JavaScript高级语法(深拷贝)

简介: 你不容错过的JavaScript高级语法(深拷贝)

下面一篇文章我们来实现一下深拷贝。


深拷贝的介绍


通过定义的方法,拷贝出的对象和原来的对象没有关系。修改任何对象都不会相互影响。


通过JSON方法来处理深拷贝


const info = JSON.parse(JSON.stringify(obj))


存在的问题:


  • 对于函数、Symbol等是无法处理的


  • 存在对象的循环引用,也会报错的


自定义深拷贝函数


  • 基本封装


  • 他只能处理基本数据类型, 对象, 数组。


  • 不能处理Symbol, Function, Set, Map类型


function isObject(value) {
      const valueType = typeof value
      return (value !== null) && (valueType === "object" || valueType === "function")
    }
    function deepClone(originValue) {
      // 判断传入的originValue是否是一个对象类型
      if (!isObject(originValue)) {
        return originValue
      }
      // 判断传入的对象是数组, 还是对象
      const newObject = Array.isArray(originValue) ? []: {}
      for (const key in originValue) { // 如果originValue是一个函数(其实任何值都不会报错)in操作符也不会报错。
        newObject[key] = deepClone(originValue[key])
      }
      return newObject
    }


  • 处理函数类型。


// 判断如果是函数类型, 那么直接使用同一个函数
      if (typeof originValue === "function") {
        return originValue
      }


  • 处理Symbol类型


  • Symbol作为值是可以直接拷贝的。


  • 由于for ... of不能遍历Symbol为key的对象,所以需要做特殊处理。


// 判断如果是Symbol的value, 那么创建一个新的Symbol
      if (typeof originValue === "symbol") {
        return Symbol(originValue.description)
      }
      // 对Symbol的key进行特殊的处理
      const symbolKeys = Object.getOwnPropertySymbols(originValue)
      for (const sKey of symbolKeys) {
        newObject[sKey] = deepClone(originValue[sKey])
      }


  • 处理Set, Map类型


  • 注意: 这里只对Set,Map类型做浅拷贝。


// 判断是否是一个Set类型
      if (originValue instanceof Set) {
        return new Set([...originValue])
      }
      // 判断是否是一个Map类型
      if (originValue instanceof Map) {
        return new Map([...originValue])
      }


  • 处理对象循环引用问题


  • 通过Map来实现,就是先把对象放进Map中。每次遍历,如果遇到循环引用,那么直接将newObject赋值给他。


  • 并且为了防止多次调用,自由变量Map中的值过多,应该将Map作为参数传递。


function isObject(value) {
      const valueType = typeof value
      return (value !== null) && (valueType === "object" || valueType === "function")
    }
    function deepClone(originValue, map = new WeakMap()) {
      // 判断是否是一个Set类型
      if (originValue instanceof Set) {
        return new Set([...originValue])
      }
      // 判断是否是一个Map类型
      if (originValue instanceof Map) {
        return new Map([...originValue])
      }
      // 判断如果是Symbol的value, 那么创建一个新的Symbol
      if (typeof originValue === "symbol") {
        return Symbol(originValue.description)
      }
      // 判断如果是函数类型, 那么直接使用同一个函数
      if (typeof originValue === "function") {
        return originValue
      }
      // 判断传入的originValue是否是一个对象类型
      if (!isObject(originValue)) {
        return originValue
      }
      if (map.has(originValue)) {
        return map.get(originValue)
      }
      // 判断传入的对象是数组, 还是对象
      const newObject = Array.isArray(originValue) ? []: {}
      map.set(originValue, newObject)
      for (const key in originValue) {
        newObject[key] = deepClone(originValue[key], map)
      }
      // 对Symbol的key进行特殊的处理
      const symbolKeys = Object.getOwnPropertySymbols(originValue)
      for (const sKey of symbolKeys) {
        // const newSKey = Symbol(sKey.description)
        newObject[sKey] = deepClone(originValue[sKey], map)
      }
      return newObject
    }



相关文章
|
4月前
|
存储 JavaScript 前端开发
Node.js的基本语法
【8月更文挑战第12天】Node.js的基本语法
154 1
|
2月前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
2月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
53 4
|
2月前
|
JavaScript 前端开发 大数据
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
38 0
|
3月前
|
JSON JavaScript 数据格式
手写JS实现深拷贝函数
本文介绍了如何实现一个深拷贝函数`deepClone`,该函数可以处理对象和数组的深拷贝,确保拷贝后的对象与原始对象在内存中互不干扰。通过递归处理对象的键值对和数组的元素,实现了深度复制,同时保留了函数类型的值和基础类型的值。
25 3
|
4月前
|
JavaScript 前端开发
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
这篇文章是JavaScript基础与实战教程的第一部分,涵盖了JavaScript的基本语法、标识符、数据类型以及如何进行强制类型转换,通过代码示例介绍了JS的输出语句、编写位置和数据类型转换方法。
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
|
4月前
|
JavaScript 前端开发
JavaScript中的深拷贝与浅拷贝
JavaScript中的深拷贝与浅拷贝
46 2
|
4月前
|
前端开发 JavaScript 程序员
前端 JavaScript 的 _ 语法是个什么鬼?
前端 JavaScript 的 _ 语法是个什么鬼?
|
4月前
|
JavaScript 前端开发
js中浅拷贝和深拷贝的区别
js中浅拷贝和深拷贝的区别
33 0
|
4月前
|
JavaScript 前端开发
js中浅拷贝,深拷贝的实现
js中浅拷贝,深拷贝的实现
37 0