Skip to content

深度克隆

【深度克隆的一般实现【渡一教育】】

  1. 传统做法 最通用,最易扩展
  2. JSON 有缺陷:
    • Map、Functoin 会被丢弃。
    • 递归会报错。
  3. 通信 MessageChannel 有缺陷:
    • 异步
    • 限制在浏览器环境中

传统做法

javascript
const cache = new WeakMap()

function deepClone(value) {
    // 原始类型不需要克隆
    if (type value !== 'object' || value === null) {
        return value
    }

    /**
     * 按具体需求,扩充类型
     */

    // 处理循环引用
    if (cache.has(value)) {
        return cache.get(value)
    }
    const result = Array.isArray(value) ? [] : {}

    // 处理类和对象
    Object.setPrototypeOf(result, Object, getPrototypeOf(value))
    // 处理循环引用
    cache.set(value, result)

    for (let key in value) {
        /**
         * 判断是否是自有属性,避免把类中的属性克隆进去
         * 只克隆对象上的属性
         */
        if (!value.hasOwnProperty(key)) {
            result[key] = deepClone(value[key])
        }
    }
    
    return result
}
javascript
class Test {
    constructor() {
        this.a = 1
        this.b = 2
    }

    c() {
        console.log('c')
    }
}

const obj = new Test()

Test.prototype.d = 1

objh = obj
console.log(obj)
console.log(deepClone(obj))

下面的函数是从狗袋那复制来的

javascript
/**
 * @description 深拷贝函数
 * @param {Object} obj 要拷贝的对象 
 */
function deepClone(obj = {}, map = new WeakMap()) {
    if (typeof obj !== 'object' || obj == null) {
        // obj不是对象或者数组,直接返回
        return obj
    }
  
    // 防止循环引用
    if (map.has(obj)) {
      return map.get(obj)
    }

    // 初始化返回结果
    let result
    if (obj instanceof Array) {
        result = []
    } else {
        result = {}
    }
    map.set(obj, result);

    for (let key in obj) {
        // 保证key不是原型的属性
        if (obj.hasOwnProperty(key)){
            // 递归
            result[key] = deepClone(obj[key], map)
        }
    }

    // 返回结果
    return result
}
评论区
评论区空空如也
发送评论
名字
0 / 20
邮箱
0 / 100
评论内容
0 / 140
由于是非实名评论,所以不提供删除功能。如果你需要删除你发送的评论,或者是其他人的评论对你造成了困扰,请 发邮件给我 。同时评论区会使用 AI + 人工的方式进行审核,以达到合规要求。

© thebestxt.cc
辽ICP备16009524号-8
本站所有文章版权所有,转载请注明出处