简介:前端面试中手写题是考察基础能力的重要环节,本文精选10个高频手写题,分上下篇详细解析实现逻辑与核心要点,助你攻克技术面试难关。
在前端技术面试中,手写题始终占据重要地位。这类题目不仅能检验开发者对语言特性的理解深度,更能体现其编码规范、边界处理能力和问题拆解思维。本文精选的10个常考题目覆盖数据结构、算法、设计模式等核心领域,每个题目均包含题目解析、实现思路、代码示例、易错点四个维度,帮助读者系统掌握解题方法。
需求:编写getType函数,返回值的精确类型(如[object Array]而非"object")。
function getType(value) {return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();}// 测试用例getType([]); // "array"getType(/regex/); // "regexp"
关键点:
Object.prototype.toString而非typeof,解决typeof null === "object"的缺陷slice(8, -1)提取类型字符串(如从"[object Array]"提取"Array")需求:实现支持循环引用的深拷贝函数。
function deepClone(obj, hash = new WeakMap()) {if (obj === null || typeof obj !== 'object') return obj;if (hash.has(obj)) return hash.get(obj); // 处理循环引用const cloneObj = Array.isArray(obj) ? [] : {};hash.set(obj, cloneObj);for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], hash);}}return cloneObj;}
优化点:
WeakMap存储已拷贝对象,避免循环引用导致的堆栈溢出hasOwnProperty过滤原型链属性需求:实现通用柯里化函数,支持多参数分步调用。
function curry(fn) {return function curried(...args) {if (args.length >= fn.length) {return fn.apply(this, args);} else {return function(...args2) {return curried.apply(this, args.concat(args2));}}}}// 使用示例const sum = curry((a, b, c) => a + b + c);sum(1)(2)(3); // 6
实现原理:
fn.length判断参数是否收集完毕curried函数积累参数this指向的正确性需求:实现compose函数,从右向左执行多个函数。
function compose(...fns) {return function(value) {return fns.reduceRight((acc, fn) => fn(acc), value);}}// 使用示例const add1 = x => x + 1;const mul2 = x => x * 2;compose(mul2, add1)(5); // (5+1)*2 = 12
应用场景:
需求:模拟实现Promise.all方法,处理异步数组。
function promiseAll(promises) {return new Promise((resolve, reject) => {const results = [];let count = 0;promises.forEach((promise, index) => {Promise.resolve(promise).then(value => {results[index] = value;count++;if (count === promises.length) resolve(results);}).catch(err => reject(err));});});}
边界处理:
需求:实现limitRequest函数,控制最大并发数。
function limitRequest(urls, limit = 5) {return new Promise(resolve => {const results = [];let current = 0;function execute() {if (current >= urls.length) {resolve(results);return;}const index = current++;fetch(urls[index]).then(res => results[index] = res).finally(() => execute()); // 完成一个后立即启动下一个}// 启动初始并发for (let i = 0; i < limit; i++) {execute();}});}
优化方向:
需求:实现createElement和render函数,构建虚拟DOM树。
function createElement(type, props, ...children) {return {type,props: {...props,children: children.map(child =>typeof child === 'object' ? child : createTextElement(child))}};}function createTextElement(text) {return { type: 'TEXT', props: { nodeValue: text } };}function render(element, container) {const dom = element.type === 'TEXT'? document.createTextNode(''): document.createElement(element.type);Object.keys(element.props).filter(key => key !== 'children').forEach(name => dom[name] = element.props[name]);element.props.children.forEach(child =>render(child, dom));container.appendChild(dom);}
核心概念:
需求:实现支持动态元素的事件委托。
function delegateEvent(parent, eventType, selector, handler) {parent.addEventListener(eventType, e => {let target = e.target;while (target !== parent) {if (target.matches(selector)) {handler.call(target, e);return;}target = target.parentNode;}});}// 使用示例delegateEvent(document.getElementById('list'),'click','.item',function(e) { console.log(this.textContent); });
优势分析:
需求:实现线程安全的单例模式。
const Singleton = (function() {let instance;function createInstance() {const object = new Object('Singleton');// 初始化代码...return object;}return {getInstance: function() {if (!instance) {instance = createInstance();}return instance;}};})();
应用场景:
需求:实现带事件名的发布订阅系统。
class EventEmitter {constructor() {this.events = {};}on(eventName, callback) {if (!this.events[eventName]) {this.events[eventName] = [];}this.events[eventName].push(callback);}emit(eventName, ...args) {const callbacks = this.events[eventName] || [];callbacks.forEach(cb => cb(...args));}off(eventName, callback) {const callbacks = this.events[eventName];if (callbacks) {this.events[eventName] = callbacks.filter(cb => cb !== callback);}}}
扩展功能:
掌握这10个手写题需要:
建议读者结合《JavaScript高级程序设计》和《你不知道的JavaScript》进行系统学习,同时通过LeetCode前端专题和开源项目贡献提升实战能力。下篇将解析剩余5个进阶题目,包括手写React Hooks、Webpack插件开发等高级内容。