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

在这里插入图片描述

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

核心特色:

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

目录

      • 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.mzph.cn/pingmian/49792.shtml

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

相关文章

人工智能与机器学习原理精解【8】

文章目录 马尔科夫过程论基础理论函数系的定义、例子和分类一、函数系的定义二、函数系的例子三、函数系的分类 勒贝格积分一、定义二、计算三、例子 参考文献 马尔科夫过程论 基础 如果 α 是 ( G 1 , A 1 ) 到 ( G 2 , A 2 ) 的可测映象&#xff0c; β 是 ( G 2 , A 2 ) 到…

jackson序列化(jackson codec)

Jackson 是一个用于 Java 平台的开源 JSON 库&#xff0c;它提供了灵活且高效的方式来处理 JSON 数据的序列化(Java对象 → JSON字符串)和反序列化(JSON 字符串→ Java对象)。 以下是 Jackson 的一些主要特点和功能&#xff1a; 高性能&#xff1a;Jackson 通过使用基于流的处理…

国内环境,怎么做开源才能兼顾生存和情怀?

回答一个朋友提的问题—— 在国内&#xff0c;开源怎么做呢&#xff1f;老夫结合自己多年在开源和商业领域的经历与见闻聊聊。 首先来说&#xff0c;毋庸置疑&#xff0c;开源是对传统的商业模式的一种颠覆&#xff0c;它以一种免费开放的姿态赢得了Hacker群体的心&#xff0c…

mac OS matplotlib missing from font(s) DejaVu Sans

如果能搜索到这篇文章&#xff0c;我猜你遇到了和我一样的问题&#xff1a;matplotlib绘图中文乱码。如下&#xff1a; 出现这个问题的原因是&#xff1a;matplotlib使用的字体列表中默认没有中文字体。 这里说一种解决方案&#xff1a;我们可以在文件中手动指定matplotlib使用…

微信小程序-使用Component方法代替Page方法构造页面

一.使用Component方法的前提条件 在小程序js文件里使用Component方法代替Page方法需要在json文件里面定义usingComponents属性 {"usingComponents": {} }二.注意事项 1.在page页面里使用的钩子函数和事件监听方法都需要写在methods对象里面 methods:{update(){thi…

WHAT - Web Components 和 Vue、React 的模块化组件

目录 Web Components介绍组件库1. Lit2. Vaadin3. Shoelace4. Stencil5. FAST6. Ionic7. UI5 Web Components8. PatternFly Elements使用和选择指南结论 与 Vue 或 React 组件的区别1. 原生 vs 框架依赖2. 样式和 DOM 隔离3. 使用和学习曲线4. 状态管理和生命周期 专题&#xf…

二叉树详解-第一篇 树以及二叉树的概念

目录 ​编辑 1.树的概念及结构 1.1树的概念 1.2树的特点 1.3树的相关概念 1.4树的表示 2.二叉树的概念及结构 2.1二叉树的概念 2.2特殊二叉树-满二叉树和完全二叉树 1.满二叉树的概念及性质 2.完全二叉树的概念及性质 2.3二叉树的性质(重点) 2.4二叉树的存储 1.顺…

LeetCode - #103 二叉树的锯齿形层序遍历

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

沉淀硬化不锈钢压缩弹簧的主要特性

沉淀硬化不锈钢&#xff0c;作为一种兼具高强度与耐腐蚀性的合金材料&#xff0c;被广泛应用于制造高性能的压缩弹簧&#xff0c;尤其是在苛刻环境下的应用需求。以下是对沉淀硬化不锈钢压缩弹簧主要特性的科普介绍&#xff1a; 良好的耐蚀性 沉淀硬化不锈钢与304不锈钢拥有相似…

做个牛奶配送小程序商城是怎样的

商家线上经营奶品&#xff0c;主要是成品包装品牌奶或散奶周边客源生意模式等&#xff0c;无论哪些模式&#xff0c;本身奶产品的需求度就不低&#xff0c;自然也有着大量客户&#xff0c;农场/品牌厂商/经销商/小摊贩&#xff0c;除了线下实体店发展外&#xff0c;线上要完善本…

SpringCloud断路器的使用与原理解析

Spring Cloud断路器是在分布式系统中实现容错的一种方式。它的原理是通过在调用链路上添加断路器,当某个服务的调用出现故障或超时时,断路器会自动迅速地切换到快速失败模式,防止故障扩散,从而保护整个系统的稳定性。 Spring Cloud断路器的使用与原理解析如下: 一、使用断…

KunDB4.0:安全能力与Oracle兼容性提升,支持跨系统多租户部署

KunDB是星环科技自主研发的分布式交易型数据库&#xff0c;高度兼容Oracle和MySQL&#xff0c;提供数据强一致、高可用、高性能、高扩展、应用透明等能力&#xff0c;可在云上和物理机上容器化部署运行&#xff0c;一站式解决企业数据存储、管理、计算与安全性问题。 过去半年…

数据结构经典测题3

1. 设有定义&#xff1a; char *p; &#xff0c;以下选项中不能正确将字符串赋值给字符型指针 p 的语句是【多选】&#xff08; &#xff09; A: pgetchar(); B: scanf("%s",p); C: char s[]"china"; ps; D: *p"china"; 答案为ABD A选项&…

SQL Server中 LOP_FORMAT_PAGE日志记录解释

在SQL Server中&#xff0c;LOP_FORMAT_PAGE是日志记录的一种类型&#xff0c;用于描述页面的格式化操作。了解LOP_FORMAT_PAGE详细的背景和任务类型有助于深入理解SQL Server的内部机制&#xff0c;尤其是在恢复和日志管理方面。以下是有关LOP_FORMAT_PAGE的详细解释&#xff…

如何优化 Selenium 和 BeautifulSoup 的集成以提高数据抓取的效率?

摘要 在互联网时代&#xff0c;数据的价值日益凸显。对于电商网站如京东&#xff0c;其商品信息、用户评价等数据对于市场分析、产品定位等具有重要意义。然而&#xff0c;由于这些网站通常使用 JavaScript 动态生成内容&#xff0c;传统的爬虫技术难以直接获取到完整数据。本…

pyaudio VAD通过声音音频值分贝大小检测没人说话自动停止录制

效果可能说话声音小可能不被监听到,需要更改QUIET_DB阈值,另外delay_time值是低于阈值多久就可以停止保存当前的语音 import pyaudio import waveimport sys import numpy as npdef record_auto(MIC_INDEX=1):开启麦克风录音,保存至temp/speech_record.wav音频文件音量超过…

洛谷 P1151 子数整数 题解

题目描述 对于一个五位数 a1​a2​a3​a4​a5​​&#xff0c;可将其拆分为三个子数&#xff1a; &#x1d460;&#x1d462;&#x1d44f;1&#x1d44e;1&#x1d44e;2&#x1d44e;3 &#x1d460;&#x1d462;&#x1d44f;2&#x1d44e;2&#x1d44e;3&#x1d44…

vue3 reactive原理(二)-代理Set和Map及ref原理

Set和Map类型的数据也属于异质对象&#xff0c;它们有特定的属性和方法用来操作自身。因此创建代理时&#xff0c;针对特殊的方法需要特殊的对待。 Vue 的ref 是基于reactive函数实现的&#xff0c;它在其基础上&#xff0c;增加了基本类型的响应性、解决reactive在解构时丢失…

目标检测原理分析

目标检测 图像分类&#xff08;一张图像只属于一个类别&#xff09;目标检测&#xff08;一张图像有N个物体&#xff09; 图像分类&#xff08;一张图像只属于一个类别&#xff09; 输入&#xff1a; 一张图像&#xff0c;image 输出&#xff1a; 这张图像属于各个预定义类别的…

【Unity实战】yield return null还是WaitForEndOfFrame

当在Unity中编写协程&#xff08;尤其是协程套无限循环&#xff09;时&#xff0c;常常会用到yield关键字来控制协程的执行流程避免程序假死。以下是常见做法&#xff1a; yield return null 当使用yield return null时&#xff0c;协程会在下一帧继续执行。这意味着协程将暂…