【🔥面试篇🔥】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 方法,以应对更多复杂的场景。

总结

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

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

相关推荐
我怎么能这么帅气几秒前
拯救排版焦虑!CSS省略号的终极指南:单行、多行、生效与失效场景全解析
前端·css
lqstyle几秒前
Redis的Set:你以为我是青铜?其实我是百变星君!
后端·面试
迷路的小绅士12 分钟前
常见网络安全攻击类型深度剖析(四):跨站脚本攻击(XSS)——分类、漏洞利用与前端安全防护
前端·安全·web安全
前端snow20 分钟前
前端全栈第一课:用typeorm向数据库添加数据
前端
小希爸爸21 分钟前
3、中医基础入门和养生
前端·javascript·后端
摆烂工程师37 分钟前
ChatGPT免费用户可以使用Deep Research啦!并且o3、o4-mini的可使用次数翻倍!
前端·后端·程序员
狂炫一碗大米饭38 分钟前
作为前端你不得不知道的浏览器相关知识1🚀
前端
_一条咸鱼_41 分钟前
揭秘 Android ListView:从源码深度剖析其使用原理
android·面试·android jetpack
_一条咸鱼_43 分钟前
深入剖析 Android NestedScrollView 使用原理
android·面试·android jetpack
_一条咸鱼_43 分钟前
揭秘 Android ScrollView:深入剖析其使用原理与源码奥秘
android·面试·android jetpack