当前位置: 首页 > news >正文

下次接好运~

以下是JavaScript面试中高频出现的“手撕代码”题目详解,涵盖核心原理、代码实现与面试应答要点,结合最新技术实践整理:


⚙️ 一、原型与继承

  1. 手撕instanceof
    原理:沿原型链向上查找,判断构造函数的prototype是否在对象原型链上。
    代码实现

    function myInstanceof(obj, constructor) {let proto = obj.__proto__;while (proto) {if (proto === constructor.prototype) return true;proto = proto.__proto__;}return false;
    }
    console.log(myInstanceof([], Array)); // true
    

    关键点:递归访问__proto__,边界条件为proto === null

  2. 手撕new操作符
    原理:创建空对象 → 绑定原型 → 执行构造函数 → 返回对象。
    代码实现

    function myNew(constructor, ...args) {const obj = Object.create(constructor.prototype);const result = constructor.apply(obj, args);return result instanceof Object ? result : obj;
    }
    function Person(name) { this.name = name; }
    const p = myNew(Person, 'Tom');
    

🔧 二、函数与this

  1. 手撕call/apply/bind
    核心思路:通过临时绑定函数到上下文对象执行。
    call实现

    Function.prototype.myCall = function(context, ...args) {context = context || window;const fn = Symbol();context[fn] = this;const res = context...args;delete context[fn];return res;
    }
    

    区别

    • apply:第二参数为数组args
    • bind:返回新函数,合并参数[...args, ...newArgs]
  2. 柯里化(Currying)
    题目:实现add(1)(2)(3) = 6
    实现

    function curry(fn) {return function curried(...args) {if (args.length >= fn.length) return fn(...args);return (...more) => curried(...args, ...more);};
    }
    const add = curry((a, b, c) => a + b + c);
    

三、异步控制

  1. 防抖(Debounce)
    场景:搜索框输入停止后触发请求。
    实现

    function debounce(fn, delay) {let timer;return (...args) => {clearTimeout(timer);timer = setTimeout(() => fn(...args), delay);};
    }
    
  2. 节流(Throttle)
    场景:滚动事件触发频率控制。
    实现

    function throttle(fn, interval) {let lastTime = 0;return (...args) => {const now = Date.now();if (now - lastTime >= interval) {fn(...args);lastTime = now;}};
    }
    
  3. 手撕Promise
    核心功能:状态机(pending/fulfilled/rejected)+ 回调队列。
    简化版

    class MyPromise {constructor(executor) {this.state = 'pending';this.value = null;this.onFulfilledCallbacks = [];const resolve = (value) => {if (this.state === 'pending') {this.state = 'fulfilled';this.value = value;this.onFulfilledCallbacks.forEach(cb => cb());}};executor(resolve);}then(onFulfilled) {return new MyPromise(resolve => {const wrapper = () => resolve(onFulfilled(this.value));if (this.state === 'fulfilled') wrapper();else this.onFulfilledCallbacks.push(wrapper);});}
    }
    

📚 四、数组操作

  1. 数组扁平化
    递归实现

    function flatten(arr) {return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flatten(cur) : cur), []);
    }
    console.log(flatten([1, [2, [3]]])); // [1,2,3]
    
  2. 数组去重
    最优解Set + 扩展运算符

    const unique = arr => [...new Set(arr)];
    
  3. 手撕Array.reduce
    核心:处理初始值 + 遍历累加

    Array.prototype.myReduce = function(callback, init) {let acc = init ?? this[0];for (let i = init ? 0 : 1; i < this.length; i++) {acc = callback(acc, this[i], i, this);}return acc;
    }
    

🧩 五、对象操作

深拷贝(Deep Clone)
处理循环引用WeakMap存储已拷贝对象

function deepClone(obj, map = new WeakMap()) {if (obj === null || typeof obj !== 'object') return obj;if (map.has(obj)) return map.get(obj);const clone = Array.isArray(obj) ? [] : {};map.set(obj, clone);for (const key in obj) {clone[key] = deepClone(obj[key], map);}return clone;
}

💡 面试应答技巧

  1. 解释思路优先:先说明设计原理(如防抖的“延迟执行”),再写代码。
  2. 边界条件处理:主动提及null判断、参数校验(如reduce的初始值)。
  3. 性能优化:如深拷贝用WeakMap避免内存泄漏。
  4. 对比原生API:说明手写版与原生差异(如Promise未实现微队列)。

⚠️ 手写题核心考察点:

  • 原型链理解(如instanceof
  • 异步控制能力(如Promise状态机)
  • 函数式编程(如柯里化)
  • 内存管理意识(如深拷贝的循环引用处理)

掌握以上题目后,可覆盖90%前端面试手撕代码环节。建议实际编码测试边界用例(如数组方法处理稀疏数组)。

http://www.dtcms.com/a/309238.html

相关文章:

  • Oracle EBS 缺少adcfgclone.pl文件
  • 一分钟了解IO-Link 系列集线器
  • LaTeX 复杂图形绘制教程:从基础到进阶
  • Deep Height Decoupling for Precise Vision-based 3D Occupancy Prediction
  • 数据结构前篇 - 深入解析数据结构之复杂度
  • Leetcode——53. 最大子数组和
  • 如何将消息转移到新 iPhone
  • 如何将联系人从三星手机转移到 iPhone
  • MySQL 高并发下如何保证事务提交的绝对顺序?
  • 转换图(State Transition Diagram)和时序图(Sequence Diagram)画图流程图工具
  • 新手向:国内外大模型体验与评测
  • 智能图书馆管理系统开发实战系列(四):后端C++ DLL开发与模块化设计
  • 一种新的分布式ID生成方案--ULID
  • ABP VNext + Dapr Workflows:轻量级分布式工作流
  • (AC)唐克的新游戏
  • Vue3中Markdown解析与渲染的完整解决方案:从安全到性能优化
  • PostgreSQL 中删除指定数据库下的所有表结构
  • 微服务的编程测评系统9-竞赛新增-竞赛编辑
  • 如何保护 Redis 实例的安全?
  • 快速排序算法详解与洛谷例题实战
  • 【PHP 构造函数与析构函数:从基础到高级的完整指南】
  • 直播平台中的美白滤镜实现:美颜SDK的核心架构与性能优化指南
  • Qt结合ffmpeg实现图片参数调节/明亮度对比度饱和度设置/滤镜的使用
  • Windows编译安装ffmpeg和sdl
  • CG--逻辑判断1
  • 实战指南:如何将Git仓库中的特定文件夹及其历史完整迁移到另一个仓库
  • Git 各场景使用方法总结
  • java8学习笔记-Stream流
  • 在uni-app中引入本地日志插件
  • 城市数字孪生之GISBox三维顶层重建白皮书