JS 手撕题高频考点

前端面试中,JS 手撕题是高频考点,主要考察 编程能力、算法思维、JS 核心知识。以下是最常见的手撕题分类 + 代码示例


目录

    • 📌 1. 手写函数柯里化
    • 📌 2. 手写 `debounce`(防抖)
    • 📌 3. 手写 `throttle`(节流)
    • 📌 4. 手写深拷贝
    • 📌 5. 手写 `new` 操作符
    • 📌 6. 手写 `call` / `apply` / `bind`
    • 📌 7. 手写 `Promise.all`
    • 📌 8. 实现 LRU 缓存
    • 📌 9. 手写 `instanceof`
    • 📌 10. 数组去重

📌 1. 手写函数柯里化

题目:实现一个 curry(fn) 函数

function curry(fn, ...args) {return args.length >= fn.length? fn(...args): (...nextArgs) => curry(fn, ...args, ...nextArgs);
}// 示例函数
function sum(a, b, c) {return a + b + c;
}const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6

📌 2. 手写 debounce(防抖)

题目:实现 debounce(fn, delay)

function debounce(fn, delay) {let timer;return function (...args) {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, args), delay);};
}// 示例:输入框搜索
const search = debounce(() => console.log("搜索 API 请求"), 500);
document.getElementById("searchInput").addEventListener("input", search);

📌 3. 手写 throttle(节流)

题目:实现 throttle(fn, delay)

function throttle(fn, delay) {let lastTime = 0;return function (...args) {const now = Date.now();if (now - lastTime >= delay) {fn.apply(this, args);lastTime = now;}};
}// 示例:鼠标滚动触发
const handleScroll = throttle(() => console.log("滚动中..."), 1000);
window.addEventListener("scroll", handleScroll);

📌 4. 手写深拷贝

题目:实现 deepClone(obj)

function deepClone(obj, map = new WeakMap()) {if (typeof obj !== "object" || obj === null) return obj;if (map.has(obj)) return map.get(obj); // 处理循环引用let clone = Array.isArray(obj) ? [] : {};map.set(obj, clone);for (let key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = deepClone(obj[key], map);}}return clone;
}// 示例
const obj = { a: 1, b: { c: 2 } };
const copy = deepClone(obj);
console.log(copy);

📌 5. 手写 new 操作符

题目:实现 myNew(fn, ...args)

function myNew(fn, ...args) {const obj = Object.create(fn.prototype); // 创建空对象并继承构造函数原型const result = fn.apply(obj, args); // 执行构造函数return result instanceof Object ? result : obj; // 处理返回值
}// 示例
function Person(name) {this.name = name;
}
const p = myNew(Person, "Alice");
console.log(p.name); // Alice

📌 6. 手写 call / apply / bind

✅ 手写 call

Function.prototype.myCall = function (context, ...args) {context = context || window;const fnKey = Symbol();context[fnKey] = this;const result = context[fnKey](...args);delete context[fnKey];return result;
};// 示例
function greet() {console.log(`Hello, ${this.name}`);
}
const obj = { name: "Alice" };
greet.myCall(obj); // Hello, Alice

✅ 手写 apply

Function.prototype.myApply = function (context, args = []) {context = context || window;const fnKey = Symbol();context[fnKey] = this;const result = context[fnKey](...args);delete context[fnKey];return result;
};

✅ 手写 bind

Function.prototype.myBind = function (context, ...args) {const self = this;return function (...innerArgs) {return self.apply(context, [...args, ...innerArgs]);};
};// 示例
const boundFn = greet.myBind(obj);
boundFn(); // Hello, Alice

📌 7. 手写 Promise.all

题目:实现 myPromiseAll(promises)

function myPromiseAll(promises) {return new Promise((resolve, reject) => {let results = [];let count = 0;if (promises.length === 0) resolve([]);promises.forEach((p, index) => {Promise.resolve(p).then(value => {results[index] = value;count++;if (count === promises.length) resolve(results);},error => reject(error));});});
}// 示例
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = new Promise(resolve => setTimeout(() => resolve(3), 1000));myPromiseAll([p1, p2, p3]).then(console.log); // [1, 2, 3]

📌 8. 实现 LRU 缓存

题目:设计一个 LRUCache

class LRUCache {constructor(capacity) {this.capacity = capacity;this.cache = new Map();}get(key) {if (!this.cache.has(key)) return -1;let value = this.cache.get(key);this.cache.delete(key);this.cache.set(key, value);return value;}put(key, value) {if (this.cache.has(key)) this.cache.delete(key);this.cache.set(key, value);if (this.cache.size > this.capacity) {this.cache.delete(this.cache.keys().next().value); // 删除最早的键}}
}// 示例
const cache = new LRUCache(2);
cache.put(1, "A");
cache.put(2, "B");
console.log(cache.get(1)); // A
cache.put(3, "C"); // 淘汰 key=2
console.log(cache.get(2)); // -1

📌 9. 手写 instanceof

题目:实现 myInstanceOf(obj, constructor)

function myInstanceOf(obj, constructor) {let proto = Object.getPrototypeOf(obj);while (proto) {if (proto === constructor.prototype) return true;proto = Object.getPrototypeOf(proto);}return false;
}// 示例
console.log(myInstanceOf([], Array)); // true
console.log(myInstanceOf({}, Array)); // false

📌 10. 数组去重

const uniqueArray = arr => [...new Set(arr)];
console.log(uniqueArray([1, 2, 2, 3])); // [1, 2, 3]

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

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

相关文章

【STM32】知识点介绍一:硬件知识

文章目录 一、电源引脚简介二、电平信号三、电路分析 一、电源引脚简介 VCC、GND、VDD和VSS是电子电路中常见的术语,代表着不同的电源引脚或电压。 VCC(Voltage at the Common Collector):VCC是指集电极(Collector&am…

3. 列表元素替换

【问题描述】给定一个列表,将列表中所有的偶数替换为0 【输入形式】输入一行,包含若干个整数,用空格分隔 【输出形式】输出替换后的列表,每个元素用空格分隔 【样例输入】1 2 3 4 5 6 7 8 9 10 【样例输出】1 0 3 0 5 0 7 0 9…

问题的根源还是解题的方案

周末的早上照例是要早醒 debug 代码的,仿佛又回到了 2014 年… 古人几天甚至几个月不洗澡,不会臭吗?有没有可能古人没有化纤类衣服,且古人的纯天然生活环境其身体菌群和现代人不同,古人就像健康的野生动物一样即使不洗…

虚拟机安装linux系统无法上网的解决方法

在虚拟环境中运行Linux系统时,有时会遇到网络连接问题,特别是在使用虚拟机软件如VMware或VirtualBox时。本文将详细介绍一种针对“虚拟机安装Linux系统无法上网”问题的解决方案,以CentOS 6.5为例,适用于其他基于NAT模式的虚拟机环…

子网划分浅度解析

文章目录 ip地址的组成不同类型ip地址的范围子网掩码默认子网掩码子网掩码如何作用的?默认子网掩码怎么作用? ip地址的组成 ip地址一般写作4位点分十进制(x.x.x.x),他们由32位二进制组成,每个x由8位二进制…

什么是 SEO(搜索引擎优化)?

您有网站吗,或者您正在考虑创建一个网站?您想吸引更多人加入您的业务吗?如果答案是肯定的,那么毫无疑问:SEO 应该是您营销工作的一部分。这是建立品牌和吸引用户访问您的网站的好方法。但它实际上意味着什么呢&#xf…

鸿蒙HarmonyOS NEXT设备升级应用数据迁移流程

数据迁移是什么 什么是数据迁移,对用户来讲就是本地数据的迁移,终端设备从HarmonyOS 3.1 Release API 9及之前版本(单框架)迁移到HarmonyOS NEXT(双框架)后保证本地数据不丢失。例如,我在某APP…

【现代深度学习技术】现代卷积神经网络04:含并行连接的网络(GoogLeNet)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…

【ESP32】ESP32与MQTT通信:实现传感器数据监测与设备控制

ESP32与MQTT通信 1 项目概览2 硬件组成3 MQTT协议解析MQTT协议简介MQTT核心概念本项目中的MQTT应用 4 MQTT Broker选择EMQX Broker其他常用MQTT Broker 5 代码解析初始化与配置MQTT消息处理发布传感器数据 6 MQTT话题TOPIC设计7 EMQX的优势在IoT项目中的体现8 MQTT通信流程9 应…

[特殊字符]《Curve DAO 系统学习目录》

本教程旨在系统学习 Curve DAO 项目的整体架构、核心机制、合约设计、治理逻辑与代币经济等内容,帮助开发者全面理解其设计理念及运作方式。 目录总览: 1. Curve 项目概览 • 1.1 Curve 是什么?主要解决什么问题? • 1.2 与其他…

每天一篇目标检测文献(六)——Part One

今天看的是《Object Detection with Deep Learning: A Review》 目录 一、摘要 1.1 原文 1.2 翻译 二、介绍 2.1 信息区域选择 2.2 特征提取 2.3 分类 三、深度学习的简要回顾 3.1 历史、诞生、衰落和繁荣 3.2 CNN架构和优势 一、摘要 1.1 原文 Due to object dete…

Arthas线上问题诊断器

Arthas是Alibaba开源的java诊断工具 解决问题 这个类从哪个jar 包加载的?为什么会报各种相关的Exception? 遇到问题无法在线上debug,不能直通过加载日志再重新发布 有什么办法可以监控到JVM的实时运行状态? …

[Lc5_dfs+floodfill] 简介 | 图像渲染 | 岛屿数量

目录 0.floodfill算法简介 1.图像渲染 题解 2.岛屿数量 题解 之前我们在 bfs 中有介绍过[Lc15_bfsfloodfill] 图像渲染 | 岛屿数量 | 岛屿的最大面积 | 被围绕的区域,现在我们来看看 dfs 又是如何解决的呢 0.floodfill算法简介 floodfill算法又叫洪水灌溉或者…

JVM类加载器详解

文章目录 1.类与类加载器2.类加载器加载规则3.JVM 中内置的三个重要类加载器为什么 获取到 ClassLoader 为null就是 BootstrapClassLoader 加载的呢? 4.自定义类加载器什么时候需要自定义类加载器代码示例 5.双亲委派模式类与类加载器双亲委派模型双亲委派模型的执行…

Chapters 15 16:What Is Architecture?Independence_《clean architecture》notes

What Is Architecture?&Independence **Chapter 15: What Is Architecture?****Key Concepts**:**Code Example: Layered Architecture**: **Chapter 16: Independence****Key Concepts**:**Code Example: Dependency Inversion & Interfaces**: **Combined Example:…

【SPP】RFCOMM 层在SPP中互操作性要求深度解析

蓝牙串口协议(SPP)通过 RFCOMM 协议实现 RS232 串口仿真,其互操作性是设备互联的关键。本文基于蓝牙核心规范,深度解析 RFCOMM 层的能力矩阵、信号处理、流控机制及实战开发,结合状态机、流程图和代码示例,…

阻塞式IO与非阻塞IO的区别

阻塞式IO与非阻塞IO的区别 1. 阻塞式IO (Blocking I/O) 定义 当程序发起一个I/O操作(如读取文件、网络数据)时,进程会被挂起(阻塞),直到操作完成或超时才会继续执行后续代码。在此期间,程序无法…

Gossip协议:分布式系统中的“八卦”传播艺术

目录 一、 什么是Gossip协议?二、 Gossip协议的应用 💡三、 Gossip协议消息传播模式详解 📚四、 Gossip协议的优缺点五、 总结: 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式&…

【C++初阶】----模板初阶

1.泛型函数 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。 2.函数模板 2.1函数模板的概念 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型…

git-- github的使用--账户和本地连接

以下指令在git 执行bash 流程:先看有没有密钥; 没有的话,在电脑生成密钥对,公钥复制到github; 要想使用https,配置令牌,注意令牌有期限问题,连接不了有可能是期限问题 一个电脑对…