# JS 基础与手写实现 ## 1. 手写 Promise ```js class MyPromise { constructor(executor) { this.state = 'pending'; this.value = undefined; this.callbacks = []; const resolve = (value) => { if (this.state !== 'pending') return; this.state = 'fulfilled'; this.value = value; this.callbacks.forEach(cb => cb.onFulfilled(value)); }; const reject = (reason) => { if (this.state !== 'pending') return; this.state = 'rejected'; this.value = reason; this.callbacks.forEach(cb => cb.onRejected(reason)); }; try { executor(resolve, reject); } catch (e) { reject(e); } } then(onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { const handle = (callback, fallback) => { try { const result = (callback || fallback)(this.value); result instanceof MyPromise ? result.then(resolve, reject) : resolve(result); } catch (e) { reject(e); } }; if (this.state === 'fulfilled') handle(onFulfilled, v => v); else if (this.state === 'rejected') handle(onRejected, e => { throw e; }); else this.callbacks.push({ onFulfilled: () => handle(onFulfilled, v => v), onRejected: () => handle(onRejected, e => { throw e; }) }); }); } } ``` ## 2. Promise.all / Promise.race ```js // Promise.all - 所有成功才成功 Promise.myAll = (promises) => { return new Promise((resolve, reject) => { const results = []; let count = 0; promises.forEach((p, i) => { Promise.resolve(p).then(val => { results[i] = val; if (++count === promises.length) resolve(results); }, reject); }); }); }; // Promise.race - 第一个完成就返回 Promise.myRace = (promises) => { return new Promise((resolve, reject) => { promises.forEach(p => Promise.resolve(p).then(resolve, reject)); }); }; ``` ## 3. 防抖与节流 ```js // 防抖:停止触发后执行 function debounce(fn, delay) { let timer = null; return function(...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; } // 节流:固定间隔执行 function throttle(fn, delay) { let last = 0; return function(...args) { const now = Date.now(); if (now - last >= delay) { last = now; fn.apply(this, args); } }; } ``` ## 4. 深拷贝(处理循环引用) ```js function deepClone(obj, map = new WeakMap()) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); if (map.has(obj)) return map.get(obj); // 处理循环引用 const clone = Array.isArray(obj) ? [] : {}; map.set(obj, clone); for (const key in obj) { if (obj.hasOwnProperty(key)) { clone[key] = deepClone(obj[key], map); } } return clone; } ``` ## 5. 函数柯里化 ```js function curry(fn) { return function curried(...args) { if (args.length >= fn.length) { return fn.apply(this, args); } return (...nextArgs) => curried(...args, ...nextArgs); }; } // 使用示例 const add = (a, b, c) => a + b + c; const curriedAdd = curry(add); curriedAdd(1)(2)(3); // 6 curriedAdd(1, 2)(3); // 6 ``` ## 6. call / apply / bind 实现 ```js // call Function.prototype.myCall = function(ctx, ...args) { ctx = ctx || window; const key = Symbol(); ctx[key] = this; const result = ctx[key](...args); delete ctx[key]; return result; }; // apply Function.prototype.myApply = function(ctx, args = []) { ctx = ctx || window; const key = Symbol(); ctx[key] = this; const result = ctx[key](...args); delete ctx[key]; return result; }; // bind Function.prototype.myBind = function(ctx, ...args) { const fn = this; return function(...newArgs) { return fn.apply(ctx, [...args, ...newArgs]); }; }; ``` ## 7. 事件总线 EventEmitter ```js class EventEmitter { constructor() { this.events = {}; } on(event, listener) { (this.events[event] ||= []).push(listener); return this; } off(event, listener) { if (this.events[event]) { this.events[event] = this.events[event].filter(l => l !== listener); } return this; } emit(event, ...args) { (this.events[event] || []).forEach(listener => listener(...args)); return this; } once(event, listener) { const wrapper = (...args) => { listener(...args); this.off(event, wrapper); }; return this.on(event, wrapper); } } ```