前端面试宝典【Javascript篇】【2】

news2024/9/22 13:27:51

在这里插入图片描述

欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。

核心特色:

  • 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知识到前沿技术,从算法挑战到框架运用,让你在实战中迅速成长。
  • 深度技术解析:不再只是表面文章,我们将带你深入技术的核心,理解每一个知识点背后的原理与- - 应用场景,让你在面试中不仅知其然,更知其所以然。
  • 高质量内容保证:每一期内容都经过精心策划与打磨,确保信息的准确性和实用性,拒绝泛泛而谈,只提供真正有价值的内容。
  • 持续更新迭代:持续关注前端领域的最新动态,及时更新专栏内容,确保你始终站在技术的最前沿。

目录

      • 4. 深拷贝和浅拷贝是两种不同的对象复制策略,主要用于复制包含复杂数据结构的对象,如对象和数组。它们之间的主要区别在于如何处理对象中的引用类型属性。
        • 浅拷贝(Shallow Copy)
        • 深拷贝(Deep Copy)
        • 实现深拷贝
        • WeakMap 和 WeakSet
        • 函数
      • 5. 柯里化函数实现
        • 柯里化函数升级版
        • 柯里化函数应用场景
      • 6. 如何让 (a == 1 && a == 2 && a == 3) 的值为true

4. 深拷贝和浅拷贝是两种不同的对象复制策略,主要用于复制包含复杂数据结构的对象,如对象和数组。它们之间的主要区别在于如何处理对象中的引用类型属性。

浅拷贝(Shallow Copy)

浅拷贝只会复制对象的第一层属性,对于对象内部的引用类型(如数组、对象、函数等),它只会复制这些类型的引用,而不是复制这些类型的内容。这意味着,如果原始对象和拷贝对象中的引用类型被修改,它们都会反映相同的数据变化,因为它们指向的是同一个内存地址。

深拷贝(Deep Copy)

深拷贝会递归地复制对象的所有层级,包括对象内部的引用类型。这意味着拷贝后的对象和原始对象完全独立,修改其中一个对象不会影响另一个对象。

实现深拷贝

在JavaScript中,可以使用递归的方式来实现深拷贝。下面是一个使用JSON方法的简单深拷贝实现,适用于基本数据类型和可序列化的对象类型:

function deepCopy(obj) {
    return JSON.parse(JSON.stringify(obj));
}

但是,这种方法有一些限制:

  • 它不能处理循环引用的对象。

  • 它不能正确复制函数和正则表达式。

  • 它不能复制对象的原型链上的属性。

为了克服这些限制,可以使用递归函数来实现一个更完整的深拷贝:

function deepCopy(obj, hash = new WeakMap()) {
    if (obj instanceof Map) return deepCopyMap(obj);
    if (obj instanceof Set) return deepCopySet(obj);
    if (obj instanceof RegExp) return new RegExp(obj);
    if (obj instanceof Date) return new Date(obj);
    if (obj === null || typeof obj !== 'object') return obj;
    if (hash.has(obj)) return hash.get(obj);

    let copy = Array.isArray(obj) ? [] : {};
    hash.set(obj, copy);

    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            copy[key] = deepCopy(obj[key], hash);
        }
    }
    return copy;
}

function deepCopyMap(map) {
    const copy = new Map();
    for (let [key, value] of map.entries()) {
        copy.set(deepCopy(key), deepCopy(value));
    }
    return copy;
}

function deepCopySet(set) {
    const copy = new Set();
    for (let value of set) {
        copy.add(deepCopy(value));
    }
    return copy;
}


WeakMap 和 WeakSet

WeakMap和WeakSet是弱引用集合,它们的键必须是对象,而且这些键在垃圾回收时会被自动清除。由于它们的弱引用性质,你无法遍历它们的所有键和值,因此通常认为它们是不可拷贝的。在实际应用中,如果你需要保存WeakMap或WeakSet的状态,可能需要考虑重新构建它们,而不是深拷贝。

函数

函数是不可深拷贝的,因为函数是代码的一部分,而不是数据。当你试图“拷贝”一个函数时,实际上你得到的是对原函数的引用。如果需要在不同上下文中使用相似的功能,应该考虑将函数定义为模块或库的一部分,而不是尝试拷贝它们。

这个函数首先检查传入的对象是否是正则表达式或日期对象,如果是,则创建相应的实例。接着,它检查对象是否是基本类型或null,如果是,则直接返回。对于引用类型,它使用WeakMap来存储已经处理过的对象,以防止无限递归。最后,它递归地复制对象的所有属性。

5. 柯里化函数实现

柯里化(Currying)是函数式编程中的一个重要概念,它允许我们将多参数函数转换为一系列单参数函数的链式调用。下面是一个通用的柯里化函数实现的例子,使用JavaScript编写:

function curry(fn) {
    const arity = fn.length; // 获取函数期望的参数数量
    function _curryInner(args) {
        // 如果提供的参数数量小于函数期望的参数数量,
        // 并且下一个参数不是一个函数(意味着用户不打算提前执行函数),
        // 则返回一个新的函数。
        if (args.length < arity) {
            return function(...moreArgs) {
                return _curryInner(args.concat(moreArgs));
            };
        }
        // 如果提供了足够的参数,或者用户传递了一个函数作为最后一个参数,
        // 则调用原始函数。
        return fn.apply(null, args);
    }

    return function(...initialArgs) {
        return _curryInner(initialArgs);
    };
}

使用这个curry函数,你可以将任何多参数函数转换为柯里化形式。例如,假设我们有一个求和函数:

function sum(a, b, c) {
    return a + b + c;
}

我们可以将其柯里化:

const curriedSum = curry(sum);

然后,我们可以按需逐步传递参数:

const result1 = curriedSum(1)(2)(3); // 结果是 6
const result2 = curriedSum(1)(2, 3); // 结果同样是 6
const result3 = curriedSum(1, 2, 3); // 结果同样是 6
柯里化函数升级版

比如要实现多个数值的相加,参数数量不定:

function curry(fn) {
    let args = [];
    // 无限制接收参数
    function _curryInner(...a) {
        args = args.concat(a);
        return _curryInner
    }
    // 终止函数,计算并返回结果
    _curryInner.endF = function(cb) {
        const res = fn(...args);
        cb(res);
    };
    return _curryInner
}
// 求和函数
function s(...args) {
    return args.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
}
const curriedSum = curry(s);
// 可以传入任意数量的参数
const result1 = curriedSum(1)(2,67,5,4)(3)(2,1,2,3)(3)
    .endF(res => {
    console.log(res);
})
柯里化函数应用场景
  1. 参数预填充(Partial Application): 柯里化可以用来预先设定函数的一些参数,从而创建特定功能的版本。例如,如果你有一个计算税费的函数,你可以预先设定税率,创建一个特定税率的计算税费的函数。
  2. 配置函数: 当你需要创建一组具有特定配置的函数时,柯里化可以派上用场。例如,你可以创建一个配置了特定数据库连接的查询函数。
  3. 事件处理: 在事件驱动的编程中,柯里化可以用来创建特定事件的处理器。例如,你可以创建一个处理点击事件的函数,其中按钮ID已经被预设。
  4. 数据处理管道: 柯里化函数可以链接在一起形成数据处理管道,每个函数负责数据流的一个特定阶段。这对于数据清洗、转换和分析特别有用。
  5. API设计: 在设计API时,柯里化可以提供更优雅的接口。例如,一个搜索API可以先设定搜索条件,然后再执行搜索,而不是一次提供所有参数。
  6. 库和框架: 许多库和框架使用柯里化来提供更灵活的API。例如,Lodash库中的许多函数都可以被柯里化。
  7. 函数组合: 柯里化函数可以更容易地与其他函数组合,形成复杂的逻辑流程。这是函数式编程中常见的模式。
  8. 减少重复代码: 通过柯里化,你可以避免在多个地方重复相同的函数调用模式,从而提高代码的可维护性。
  9. 延迟执行: 柯里化可以用来延迟函数的执行,直到所有必要的参数都被提供。这对于异步编程和需要按顺序处理参数的情况特别有用。
  10. 优化性能: 在某些情况下,柯里化可以帮助优化性能,尤其是当函数的参数集相对固定时,可以缓存中间结果以避免重复计算。

6. 如何让 (a == 1 && a == 2 && a == 3) 的值为true

a定义为一个对象,重写对象的toString方法,定义一个计数器,调用一次toString,+1,这样就可以实现这个需求

let counter = 0;
let a = {
    toString: () => {
        if (counter === 0) {
            counter++;
            return '1';
        } else if (counter === 1) {
            counter++;
            return '2';
        } else if (counter === 2) {
            counter++;
            return '3';
        } else {
            // 防止无限循环,当counter超过预期值时返回一个确定的值
            return '1';
        }
    }
}

console.log((a == 1 && a == 2 && a == 3))

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

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

相关文章

Flink之重启策略

目录 1、固定延迟重启策略 2、失败率重启策略 3、不重启策略 在设置完 CheckPoint() 检查点机制后&#xff0c;不设置重启策略的话&#xff0c;&#xff0c;可以无限重启程序&#xff0c;那么设置的检查点机制也就没有什么意义了。因此&#xff0c;在生产实践中&#xff0c;…

笔记本检测工具 | 爱回收笔记本质检系统 v1.9.6

软件简介 爱回收笔记本质检系统是一款专为笔记本电脑硬件检测而设计的软件。它以其快速的检测速度、简便的操作流程和直观的检测结果&#xff0c;为用户提供了一种高效、易懂的硬件检测解决方案。 这款软件不仅适用于对电脑硬件有一定了解的用户&#xff0c;也特别适合对硬件…

Sentinel隔离、降级、授权规则详解

文章目录 Feign整合Sentinel线程隔离熔断降级授权规则自定义异常结果 上一期教程讲解了 Sentinel 的限流规则&#xff1a; Sentinel限流规则&#xff0c;这一期主要讲述 Sentinel 的 隔离、降级和授权规则 虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还…

【玩转C语言】第五讲--->数组-->一维和多维深度理解

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 引言&#xff1a; 大家好&#xff0c;我是坊钰&#xff0c;为了让大家深入了解C语言&#xff0c;我开创了【玩转C语言系列】&#xff0c;将为大家介绍C语言相关知识…

你还在为文件翻译烦恼吗?试试这四款神器,轻松搞定一切!

现如今的信息传播速度不断得加快&#xff0c;无论是中外交流还是学习&#xff0c;也越来越多小语种出现在我们的工作和生活当中来了&#xff0c;其中不伐一些文件批量的形式&#xff0c;所以今天就具体来探讨一下&#xff0c;关于文件翻译的四款辅助工具&#xff1a; 一、福昕在…

openGauss触发器详解

openGauss 是一款开源关系型数据库管理系统&#xff0c;广泛应用于企业级应用中。随着数据量的增长和业务逻辑的复杂化&#xff0c;数据库管理和操作的自动化需求越来越高。触发器&#xff08;Triggers&#xff09;作为数据库中重要的编程工具&#xff0c;能够极大地简化复杂操…

广州机房服务器搬迁布线方案

友力科技&#xff08;广州&#xff09;有限公司&#xff0c;专业从事数据中心机房建设、改造和搬迁工程。友力科技&#xff08;广州&#xff09;有限公司提供的服务内容包括但不限于&#xff1a;原数据中心设备下架准备、沿途运输、新数据中心上架运行、数据迁移等。 友力科技…

前端面试细节重难点(十二)(已工作|做分享)

1、如何区分在react、vue和js中的是否传递e参数&#xff1f;事件对象e都要通过event作为实参显示传递形参才可接收到吗&#xff1f; 答&#xff1a;&#xff08;1&#xff09;在原生JavaScript中&#xff1a;事件对象e需要通过函数参数显式传递。 &#xff08;2&#xff09;在R…

观测云加入华为云「新加坡云联盟」,引领亚太创新潮流

7月19日&#xff0c;「新加坡云联盟」在华为云新加坡峰会2024上正式宣告成立。这一创新的联合不仅是新加坡乃至整个亚太地区云服务领域的重要里程碑&#xff0c;更是全球数字化转型进程中的关键一步。 观测云作为联盟的首批成员之一&#xff0c;在成立仪式上精彩亮相&#xff0…

探索能源管理体系认证的意义与实施

能源管理体系&#xff08;Energy Management System, EnMS&#xff09;是一个综合性的框架&#xff0c;旨在帮助企业系统地管理能源使用&#xff0c;提升能源效率&#xff0c;实现可持续发展的目标。这个体系包括了企业的组织结构、职责分配、惯例、程序、过程以及资源管理。通…

Linux中为qt添加opencv

一. 安装OpenCV库&#xff1a; 打开终端&#xff0c;输入以下命令安装OpenCV&#xff1a; sudo apt-get update sudo apt-get install libopencv-dev二. 配置Qt项目 在Qt Creator中打开项目&#xff0c;然后编辑.pro文件&#xff0c;添加以下内容&#xff1a; INCLUDEPATH …

2024年必备的9大CRM工具选购指南

本文介绍的工具有&#xff1a;纷享销客、Zoho CRM、八百客、红圈通、简道云、简信CRM、Salesforce、HubSpot CRM、Apptivo。 在选择合适的CRM系统时&#xff0c;许多企业面临着功能繁多、选择困难的痛点。对于中小企业来说&#xff0c;找到一个既能提高客户关系管理效率&#x…

Java基础-Java多线程机制

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、引言 二、多线程的基本概念 1. 线程与进程 2. 多线程与并发 3. 多线程的优势 三、Java多线程的实…

GUL图形化界面操作(上部)

目录 AWT Frame对象&#xff1a;创建窗口 ​编辑 该对象相关的属性 设置窗口大小&#xff08;对象.setsize(int,int)&#xff09; 让窗口可以显现出来&#xff08;对象.setVisible(bool)&#xff09; 设置窗口标题&#xff08;对象.setTitle(String)&#xff09; 设置窗…

MySQL学习(14):索引使用规则

1. 索引语法 #创建索引 create [unique|fulltext] index 索引名 on 表名 (字段名,...); #字段可以有多个 #如果不加unique或fulltext&#xff0c;那么将创建一个普通索引 #在InnoDB引擎小&#xff0c;创建的索引默认是Btree结构#查看索引 show index from 表名;#删除索引 drop…

折叠群控FPV穿越机技术详解

折叠群控FPV穿越机技术是一个结合了多项高端技术和飞行理念的创新系统。以下是该技术的详细解析&#xff1a; 1. 技术概述&#xff1a; - FPV穿越机&#xff1a;FPV&#xff0c;全称First Person View&#xff0c;即“第一人称视角”&#xff0c;是指通过无人机上搭载的摄像头&…

Python+Pytest+Allure+Yaml+Pymysql+Jenkins+GitLab运行原理

PythonPytestAllureYamlPymysqlJenkinsGitLab运行原理逻辑及调用关系 GitLab代码仓&#xff1a; Jenkins工作空间&#xff1a; 代码&#xff1a; 测试报告展示&#xff1a;

医疗器械上市欧美,需要什么样的网络安全相关申报文件?

医疗器械在欧美上市时&#xff0c;需要提交的网络安全相关申报文件主要包括以下几个方面&#xff0c;这些要求基于欧美地区的法律法规和监管机构的指导文件。 一、美国FDA要求 1. 网络安全管理计划 内容&#xff1a;制造商需要提交一份网络安全管理计划&#xff0c;该计划应包含…

blender顶点乱飞的问题解决

初学blender&#xff0c;编辑模式下移动某些顶点&#xff0c;不管是移动还是滑动都会出现定点乱飞的问题&#xff0c;后来才发现是开了吸附工具的原因&#xff01;&#xff01;&#xff01;&#xff01; 像下面这样&#xff0c;其实我只是在Z轴上移动&#xff0c;但是就跑的很…

经纬恒润与奇瑞汽车签订新能源项目重点供应商合作协议,共同开启合作新篇章

近日&#xff0c;2024年国家级芜湖经开区汽车零部件生态大会成功举行&#xff0c;经纬恒润受邀出席&#xff0c;与行业各伙伴齐聚经开区&#xff0c;同绘发展蓝图&#xff0c;助力经开区汽车产业高质量发展。会上&#xff0c;经纬恒润与奇瑞汽车签署合作协议&#xff0c;成为奇…