跟着B站前端面试总结回顾前端基础知识(二)

news2024/12/23 12:26:38

深拷贝与浅拷贝

在JavaScript中,深拷贝是一个常见的需求,特别是在处理复杂数据结构(如对象、数组等)时,需要确保原始数据不被修改。下面通过表格形式列出几种常见的深拷贝方法,并简要说明其优缺点。

方法优点缺点
JSON 方法1. 简单快捷,一行代码即可实现。1. 无法处理函数、undefinedSymbolRegExp等特殊对象。
2. 适用于大多数基本数据类型和简单对象结构。2. 可能会丢失对象的原型链。
3. 递归对象(对象中包含自身引用)会导致无限循环。
手动递归1. 可以精确控制拷贝过程,包括如何处理特殊对象。1. 实现复杂,需要手动处理各种数据类型和特殊情况。
2. 可以保留对象的原型链(如果需要)。2. 性能可能不如其他自动化方法,特别是在处理大型对象时。
  • JSON 方法(如JSON.parse(JSON.stringify(obj)))虽然简单,但因其局限性,并不适用于所有场景。
  • 手动递归方法虽然灵活,但实现起来较为复杂,特别是在处理复杂数据结构时。

递归实现深拷贝

当然,下面是一个利用递归实现的JavaScript简单深拷贝函数的示例。这个函数将处理对象、数组以及它们的嵌套结构,但为了简化,我们不会处理像DateRegExpMapSet等特殊对象类型,也不会处理函数对象(因为函数在JavaScript中是按引用传递的,且深拷贝函数对象通常不是必要的或期望的)。

function deepClone(obj) {  
    // 对于非对象或null,直接返回  
    if (obj === null || typeof obj !== 'object') {  
        return obj;  
    }  
  
    // 初始化拷贝目标  
    let cloneObj;  
  
    // 处理数组  
    if (Array.isArray(obj)) {  
        cloneObj = [];  
        obj.forEach(item => {  
            cloneObj.push(deepClone(item)); // 递归拷贝数组中的每一项  
        });  
    }  
    // 处理对象  
    else {  
        cloneObj = {};  
        Object.keys(obj).forEach(key => {  
            cloneObj[key] = deepClone(obj[key]); // 递归拷贝对象的每一个属性值  
        });  
    }  
  
    return cloneObj;  
}  
  
// 示例使用  
const original = {  
    a: 1,  
    b: { c: 2, d: [3, 4] },  
    e: [5, 6, { f: 7 }]  
};  
  
const cloned = deepClone(original);  
console.log(cloned); // 输出深拷贝后的对象  
console.log(cloned.b.d === original.b.d); // false,说明数组也是深拷贝的  
console.log(cloned.e[2].f === original.e[2].f); // false,说明嵌套对象也是深拷贝的

在JavaScript中,实现一个利用递归的深拷贝函数可以处理大多数数据类型,包括对象、数组、以及它们的嵌套结构。下面是一个简单的实现示例:

function deepClone(obj, hash = new WeakMap()) {  
    // 对于非对象或null,直接返回  
    if (obj === null || typeof obj !== 'object') {  
        return obj;  
    }  
  
    // 如果对象已经存在于哈希表中,则直接返回其引用  
    if (hash.has(obj)) {  
        return hash.get(obj);  
    }  
  
    let cloneObj;  
  
    // 处理数组  
    if (Array.isArray(obj)) {  
        cloneObj = [];  
        hash.set(obj, cloneObj);  
        obj.forEach(item => {  
            cloneObj.push(deepClone(item, hash));  
        });  
    }  
    // 处理Date对象  
    else if (obj instanceof Date) {  
        cloneObj = new Date(obj);  
    }  
    // 处理RegExp对象  
    else if (obj instanceof RegExp) {  
        // 注意:RegExp的flags属性在ES6中引入  
        const flags = obj.flags ? `${obj.source}/${obj.flags}` : `${obj.source}/${(obj.global ? 'g' : '') + (obj.ignoreCase ? 'i' : '') + (obj.multiline ? 'm' : '') + (obj.unicode ? 'u' : '') + (obj.sticky ? 'y' : '')}`;  
        cloneObj = new RegExp(flags, obj.flags);  
    }  
    // 处理普通对象  
    else {  
        cloneObj = {};  
        hash.set(obj, cloneObj);  
        Object.keys(obj).forEach(key => {  
            cloneObj[key] = deepClone(obj[key], hash);  
        });  
  
        // 如果需要保持原型链,可以添加以下代码  
        // Object.setPrototypeOf(cloneObj, Object.getPrototypeOf(obj));  
    }  
  
    return cloneObj;  
}  
  
// 示例使用  
const original = {  
    a: 1,  
    b: { c: 2, d: [3, 4] },  
    c: new Date(),  
    d: /abc/gi,  
    e: function() { console.log('hello'); },  
    f: {  
        g: original // 循环引用  
    }  
};  
  
const cloned = deepClone(original);  
console.log(cloned);  
console.log(cloned.f.g === cloned); // true,因为处理了循环引用

注意:

  1. 这个函数使用了WeakMap来存储已经拷贝过的对象,以避免循环引用导致的无限递归。
  2. 对于特殊对象如DateRegExp,我们分别进行了特殊处理。
  3. 函数默认不保持原型的继承关系,如果需要,可以取消注释Object.setPrototypeOf相关的代码行。
  4. 函数能够处理函数对象,但请注意,函数对象在JavaScript中是按引用传递的,即使进行了深拷贝,函数本身还是同一个函数,只是函数对象作为属性被复制到了新的对象中。
  5. 对于更复杂的对象(如MapSetBlobFile等),你可能需要添加额外的逻辑来支持它们的深拷贝。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2082666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AI模型:追求全能还是专精?】

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《热点时事》 期待您的关注 目录 引言 ​编辑 一:AI模型的全面评估和比较 二:AI模型的专精化和可扩展性…

宝塔安装yasd 远程调试 swoole

一、服务器安装yasd 1.安装yasd 按照官方文档,Yasd调试器官方文档 yum install boost boost-develgit clone https://github.com/swoole/yasd.gitcd yasdphpize --clean && phpize && ./configure --with-php-config/www/server/php/74/bin/php…

筛质数(线性筛法)

线性筛法: 假设有一个非质数 x,那么这个数可以被表示为一个最小质因数和一个因子相乘的形式 如 x 12 ,那么 x 2*6 其中:2 就是 12 的最小质因数, 6 就是另一个因子 线性筛法就是利用每个数的最小质因数筛掉这个非…

做谷歌seo花钱多吗?

一分钱一分货,哪怕你是自己一个人做谷歌seo,服务器,域名的成本也是成本,当然,花费可能还少,但其中的时间精力,以及有没有效果,你大可自己掂量一下 你如果只是想随便做做,…

SSM框架之Mybatis框架

前言 什么是框架? 框架就是对技术的封装,将基础的技术进行封装,便于程序员使用,提高开发效率 ssm框架是什么? ssm包括spring、springMvc、Mybatis,是后端企业级开发时会使用到的框架组合,在…

python实战一:合并多个Excel中数据

看不懂可以跟着视频学一下,关于基础课程项目也可以私聊我! 视频源码: 链接:https://pan.quark.cn/s/2055653f735b 之前我们已经学习了如何读取和写入Execl数据,今天我们来用一个实例来进行表格的合并。如下是 2021年…

离散数学中的逻辑基础(1)

目录 引言 1. 命题及其逻辑运算 2. 逻辑等价与范式 3. 逻辑推理规则 4. 逻辑问题练习 5. 总结 引言 逻辑是离散数学的核心概念之一,它用于精确描述数学命题并分析其关系。逻辑不仅是数学证明的基础,也是计算机科学中算法设计和编程的基石。本篇文…

【STM32】STM介绍

一、嵌入式与STM32 1.嵌入式 除了桌面PC之外,所有的控制类设备,都称之嵌入式。 1 ARM概述 1.1 历史 1978年,物理学家赫尔曼豪泽(Hermann Hauser)和工程师Chris Curry,在英国剑桥创办了CPU公司&#xff…

识别不到开发板串口问题(故事版)

最近电脑重新刷机了,很多东西都没了,很伤心。但也是锻炼自己基本功的能力。 我在用vscode开发ESP32的时候,发现一直识别不到串口,很纳闷,以为笔记本端口坏了? 转念一想觉得是因为没有加驱动 当时下面有一…

大模型学习应用 3: AutoDL 平台 transformers 环境搭建及模型部署使用(持续更新中)

之前我们学习了在和鲸的预配置好的平台上进行学习,在工作中并不现实,本期我们的目标是将已有模型部署到云端进行运行 配置环境:RTX 4090D(24GB) python 3.12(ubuntu22.04) 参考文章:AutoDL平台transformers环境搭建 目录 注册及选择算力新建…

E6000物联网主机:打造智慧楼宇的未来

智慧楼宇,作为现代建筑领域的璀璨明星,正以其独特的魅力和强大的功能改变着我们的生活和工作方式。它并非简单的建筑与技术的叠加,而是通过先进的信息技术和智能化系统的深度融合,实现对建筑内各项设施和服务的高效管理与优化。 智…

Mac怎么安装谷歌浏览器

谷歌浏览器凭借其强大的功能,成为广大用户的首选浏览器。其中Mac用户在进行下载和安装时,可能会出现一些困难。为了帮助大家顺利的在Mac系统中成功安装,下面就给大家详细分享Mac安装谷歌浏览器指南,希望对你有所帮助。 Mac安装谷歌…

xss-labs通关攻略 16-20关

第16关 ?keyword<img%0asrc"1.jpg"%0aοnerrοralert(1)> 第17关 查看源代码 输入 ?arg01a&arg02 οnmοuseοveralert("aini") 第18关 直接输入 ?arg01a&arg02 οnmοuseοveralert("aini") 第19关 需要下载一个flash 输…

国内纵向科研项目梳理

文章目录 1. 2023 年以后2. 2023 年以前2.1 国家重点研发计划2.1.1 重点专项 2.2 国家科技重大专项 3. 附&#xff1a;国家级和省部级科研项目列表 1. 2023 年以后 2023 年&#xff0c;根据新的国务院机构改革方案&#xff0c;科技部现有的多项管理职责和多个下属机构都将被分…

6款自动生成文章的软件,生成文章好用、操作简单

作为一名专业创作者&#xff0c;我深知内容生产的压力和挑战。在追求效率的同时&#xff0c;保持文章的质量和原创性是至关重要的。最近&#xff0c;我亲测了6款自动生成文章的软件&#xff0c;发现它们不仅操作简便&#xff0c;而且生成的文章质量令人满意。以下是我对这6款软…

ctfhub-web-SSRF(FastCGI协议-DNS重绑定 Bypass)

less-6 FastCGI协议 步骤一&#xff1a;开启环境&#xff0c;查看提示 步骤二&#xff1a;对一句话木马进行base64编码&#xff1a;<?php eval($_POST[cmd]);?> echo "PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOz8" | base64 -d > 1.php 步骤三&#xff1a;利…

#C++ 笔记一

重点&#xff1a;面试考试大概率会涉及&#xff0c;需要不借助任何资料掌握。 掌握&#xff1a;面试考试可能涉及&#xff0c;需要不借助任何资料掌握 熟悉&#xff1a;面试考试可能涉及&#xff0c;可以稍微参考资料掌握 了解&#xff1a;面试考试小概率涉及&#xff0c;能吹吹…

获取文件属性/库Lib

获取文件属性 stat 函数 man 2 stat #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>int stat(const char *path, struct stat *buf); 功能&#xff1a;获取文件属性 参数&#xff1a; path&#xff1a;文件路径名buf&#xff1a;保存文…

最新黑名单查询录入系统_全开源源码

最新黑名单查询录入系统_全开源源码 前端html 后端layui 操作部分都采用API接口的方式实线 集结了layui表格的多数据操作&#xff0c;添加&#xff0c;批量删除&#xff0c;分页&#xff0c;单项删除 后台数据修改采用绑定参数的形式来进行修改可以很好的预防数据库注入…

【Python入门】第3节 循环语句

&#x1f4d6;第3节 循环语句 ✅while循环的基础语法✅while循环的嵌套✅while循环的嵌套案例✅for循环的基础语法&#x1f9ca;基础语法&#x1f9ca;range语句&#x1f9ca;变量作用域 ✅for循环的嵌套应用✅循环中断 : break和continue ✅while循环的基础语法 只要条件满足…