一、函数相关
1. 手写 call
Function.prototype.myCall = function (context, ...args) {
context = context || window
const fn = Symbol('fn')
context[fn] = this
const res = context[fn](...args)
delete context[fn]
return res
}
2. 手写 apply
Function.prototype.myApply = function (context, args) {
context = context || window
const fn = Symbol('fn')
context[fn] = this
const res = args ? context[fn](...args) : context[fn]()
delete context[fn]
return res
}
3. 手写 bind
Function.prototype.myBind = function (context, ...args) {
const fn = this;
return function (...rest) {
return fn.apply(context, [...args, ...rest]);
};
};
4. 手写 new
function myNew(Constructor, ...args) {
const obj = Object.create(Constructor.prototype)
const res = Constructor.apply(obj, args)
return typeof res === 'object' && res !== null ? res : obj
}
5. 手写柯里化 curry
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return (...next) => curried.apply(this, [...args, ...next]);
}
};
}
二、防抖 & 节流
6. 手写防抖 debounce
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
7. 手写节流 throttle
function throttle(fn, delay) {
let last = 0
return function (...args) {
const now = Date.now()
if (now - last > delay) {
fn.apply(this, args)
last = now
}
}
}
三、对象 & 数组
8. 手写深拷贝 deepClone
function deepClone(obj, map = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj
if (map.has(obj)) return map.get(obj)
const res = Array.isArray(obj) ? [] : {}
map.set(obj, res)
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
res[key] = deepClone(obj[key], map)
}
}
return res
}
9. 手写 instanceof
function myInstanceof(obj, Constructor) {
let proto = Object.getPrototypeOf(obj)
while (proto) {
if (proto === Constructor.prototype) return true
proto = Object.getPrototypeOf(proto)
}
return false
}
10. 手写 Object.create
function myCreate(proto) {
function F() {}
F.prototype = proto;
return new F();
}
11. 手写数组扁平化 flat
function flat(arr) {
return arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flat(cur) : cur), []);
}
12. 手写数组去重
function unique(arr) {
return [...new Set(arr)];
}
四、Promise 相关
13. 手写简易版 Promise
class MyPromise {
constructor(executor) {
this.state = 'pending'
this.value = null
this.callbacks = []
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
this.callbacks.forEach(cb => cb(value))
}
}
executor(resolve)
}
then(onFulfilled) {
if (this.state === 'fulfilled') {
onFulfilled(this.value)
} else {
this.callbacks.push(onFulfilled)
}
}
}
14. 手写 Promise.all
Promise.myAll = function (promises) {
return new Promise((resolve, reject) => {
const res = []
let count = 0
promises.forEach((p, i) => {
Promise.resolve(p).then(val => {
res[i] = val
count++
if (count === promises.length) resolve(res)
}, reject)
})
})
}
15. 手写 Promise.race
Promise.myRace = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach(p => Promise.resolve(p).then(resolve, reject));
});
};
五、工具类
16. 手写事件发布订阅 EventEmitter
class EventEmitter {
constructor() {
this.events = {};
}
on(event, fn) {
(this.events[event] = this.events[event] || []).push(fn);
}
emit(event, ...args) {
this.events[event]?.forEach(fn => fn(...args));
}
off(event, fn) {
this.events[event] = this.events[event]?.filter(f => f !== fn);
}
}
17. 手写 JSON.stringify(简化版)
function myStringify(obj) {
if (obj === null) return "null";
if (typeof obj === "string") return `"${obj}"`;
if (typeof obj === "object") {
if (Array.isArray(obj)) {
return `[${obj.map(myStringify).join(",")}]`;
}
return `{${Object.keys(obj).map(k => `"${k}":${myStringify(obj[k])}`).join(",")}}`;
}
return String(obj);
}
18. 手写 JSON.parse(简化版)
function myParse(str) {
return eval('(' + str + ')');
}
19. 手写 LRU 缓存
class LRUCache {
constructor(limit) {
this.limit = limit;
this.map = new Map();
}
get(key) {
if (!this.map.has(key)) return -1;
const val = this.map.get(key);
this.map.delete(key);
this.map.set(key, val);
return val;
}
put(key, val) {
if (this.map.has(key)) this.map.delete(key);
if (this.map.size >= this.limit) this.map.delete(this.map.keys().next().value);
this.map.set(key, val);
}
}
20. 手写函数缓存(记忆化)
function memoize(fn) {
const cache = {}
return function (...args) {
const key = JSON.stringify(args)
if (cache[key]) return cache[key]
return cache[key] = fn(...args)
}
}