MST

星途 面试题库

面试题:JavaScript深拷贝的复杂场景处理

在JavaScript中,如果要对一个包含循环引用、函数、正则表达式等复杂数据结构的对象进行深拷贝,如何实现一个健壮的深拷贝函数?请详细说明思路并编写代码实现。
24.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 处理基本数据类型,直接返回。
  2. 对于函数,直接返回原函数(因为函数在深拷贝时通常不希望克隆新的实例,而是保持引用一致)。
  3. 对于正则表达式,创建新的正则表达式实例。
  4. 对于日期对象,创建新的日期对象并传入原日期对象的值。
  5. 对于数组和对象,创建新的数组或对象,并递归地对其属性进行深拷贝。在递归过程中,要处理循环引用,通过一个Map来记录已经拷贝过的对象,避免无限递归。

代码实现

function deepClone(obj, map = new Map()) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (obj instanceof Function) {
        return obj;
    }

    if (obj instanceof RegExp) {
        return new RegExp(obj.source, obj.flags);
    }

    if (obj instanceof Date) {
        return new Date(obj.getTime());
    }

    if (map.has(obj)) {
        return map.get(obj);
    }

    let clone;
    if (Array.isArray(obj)) {
        clone = [];
        for (let i = 0; i < obj.length; i++) {
            clone[i] = deepClone(obj[i], map);
        }
    } else {
        clone = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                clone[key] = deepClone(obj[key], map);
            }
        }
    }

    map.set(obj, clone);
    return clone;
}