【🔥面试篇🔥】JavaScript 对象复制:我们谈浅拷贝与深拷贝

前言

在 JavaScript 中,处理对象复制是我们在日常开发中不可避免的任务之一。让我们通过深入研究一段简单的代码来了解浅拷贝和深拷贝的概念,以及它们在 JavaScript 中的实际运用。

一、什么是浅拷贝和深拷贝?

浅拷贝:浅拷贝是一种复制对象的方法,它创建一个新对象,并复制原始对象的属性值。然而,如果属性值是对象,浅拷贝只会复制对象的引用而不是对象本身。这意味着新对象和原始对象之间共享相同的嵌套对象。

深拷贝:深拷贝是一种复制对象的方法,它创建一个新对象,并递归地复制原始对象的所有属性及其嵌套属性。这确保了新对象和原始对象之间的完全独立性,即使属性值是对象,它们也是相互独立的。

二、浅拷贝的实现原理

在浅拷贝中,虽然创建了一个新的对象,但如果原始对象的属性值是对象,浅拷贝只会复制对象的引用而不是对象本身。这就意味着,如果修改了原始对象中嵌套对象的属性,浅拷贝的对象也会受到影响。

浅拷贝的实现原理非常简单,它只是复制原始对象的属性值,而对于嵌套对象,则复制它们的引用。这可以通过遍历对象属性并将它们复制到一个新对象来实现。

javascript 复制代码
function shallowCopy(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    const newObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }

    return newObj;
}

// 示例
let originalObject = {
    name: 'John',
    age: 25,
    hobbies: ['reading', 'coding']
};

let shallowCopiedObject = shallowCopy(originalObject);

在上述示例中,shallowCopy 函数通过遍历 originalObject 的属性并将它们复制到新对象 shallowCopiedObject 中,实现了浅拷贝。

三、 深拷贝的实现原理

深拷贝会递归地复制原始对象及其嵌套对象的所有属性,确保拷贝后的对象与原始对象完全独立。因此,修改原始对象中的属性不会影响深拷贝后的对象。

深拷贝的实现原理相对复杂一些,因为它需要递归地处理对象的嵌套属性。下面是一个简单的深拷贝实现:

javascript 复制代码
function deepCopy(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (Array.isArray(obj)) {
        return obj.map(deepCopy);
    }

    const newObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = deepCopy(obj[key]);
        }
    }

    return newObj;
}

// 示例
let originalObject = {
    name: 'John',
    age: 25,
    hobbies: ['reading', 'coding']
};

let deepCopiedObject = deepCopy(originalObject);

在这个示例中,deepCopy 函数通过递归地处理对象的属性,确保了嵌套对象的完全独立性。对于数组,使用 map 方法来处理每个元素的深拷贝。这样就实现了深拷贝,新对象 deepCopiedObject 完全独立于原始对象。

四、手写浅拷贝

浅拷贝可以通过简单地复制对象的属性来实现。下面是一个基本的浅拷贝实现:

javascript 复制代码
function shallowCopy(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    const newObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }

    return newObj;
}

// 示例
let originalObject = {
    name: 'John',
    age: 25,
    hobbies: ['reading', 'coding']
};

let shallowCopiedObject = shallowCopy(originalObject);
console.log(shallowCopiedObject);

五、手写深拷贝

深拷贝需要递归地复制对象的所有嵌套属性。以下是一个简单的深拷贝实现:

javascript 复制代码
function deepCopy(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    if (Array.isArray(obj)) {
        return obj.map(deepCopy);
    }

    const newObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = deepCopy(obj[key]);
        }
    }

    return newObj;
}

// 示例
let originalObject = {
    name: 'John',
    age: 25,
    hobbies: ['reading', 'coding']
};

let deepCopiedObject = deepCopy(originalObject);
console.log(deepCopiedObject);

这两个函数都是基本的实现,适用于一般情况。但需要注意,对于某些特殊情况,比如对象包含函数、循环引用等,这样的简单实现可能会有限制。在实际开发中,你可能会考虑使用现有的库,比如 lodashclonecloneDeep 方法,以应对更多复杂的场景。

总结

浅拷贝和深拷贝是在处理对象复制时需要着重考虑的关键概念。我们需要理解它们之间的区别,并在项目中明智地选择适当的复制方式,以便更好地管理和维护我们的代码。

通过这篇文章,我们希望你对浅拷贝和深拷贝有了更清晰的认识,并能在实际项目中明智地选择适当的对象复制方式,以确保我们的代码更加稳健和可维护。

相关推荐
Petrichoe1 分钟前
通过@Transactional常见的失效场景带你通俗理解SpringAOP的原理
面试
再学一点就睡2 分钟前
双 Token 认证机制:从原理到实践的完整实现
前端·javascript·后端
wallflower20204 分钟前
滑动窗口算法在前端开发中的探索与应用
前端·算法
蚂蚁绊大象5 分钟前
flutter第二话题-布局约束
前端
a_blue_ice5 分钟前
JAVA 面试 MySQL
java·mysql·面试
龙在天6 分钟前
我是前端,scss颜色函数你用过吗?
前端
Mapmost14 分钟前
单体化解锁3DGS场景深层交互价值,让3DGS模型真正被用起来!
前端
幻灵尔依41 分钟前
前端编码统一规范
javascript·vue.js·代码规范
欢脱的小猴子41 分钟前
VUE3加载cesium,导入czml的星座后页面卡死BUG 修复
前端·vue.js·bug
高级测试工程师欧阳43 分钟前
CSS 基础概念
前端·css·css3