防抖
const debounce = (fn,delay=300) =>{ let timer = null return function(...args){ clearTimeout(timer) timer = setTimeout(()=>fn.apply(this.args),delay) } }节流
const throttle = (fn,delay=300)=>{ let lock = false return function(...args){ if(!lock){ lock = true setTimeout((arg)=>{ fn.apply(this.args) lock = false },delay) } } }深拷贝
const deepClone = (obj,map = new Weepmap()) =>{ if(obj === null || type obj != 'object') return obj if(map.has(obj)) return map.get(obj) const target = Array.isArray(obj) ? [] : {} map.set(obj,target) Reflect.ownKeys(obj).forEach(key => { target[key] = deepClone(obj[key],map) }) return target }手写Promise 简易版
class MyPromise{ constructor(executor) { this.state = 'pending' this.val = null this.onFulfiled = [] this.onRejected = [] const resolve = v =>{ if(this.state != 'pending') return this.state = 'fulfiled' this.val = v this.onFulfiled.forEach(fn => fn(v)) } const reject = e => { if(this.state != 'pending') return this.state = 'rejected' this.val = e this.onRejected.forEach(fn => fn(e)) } try { executor(resolve, reject)} catch(err) {reject(err)} } then(suc, err) { suc = suc || (v => v) err = err || (e => { throw e }) return new MyPromise((res, rej) => { const cb = fn => v => setTimeout(() => { try { const r = fn(v); res(r) } catch (e) { rej(e) } }) if (this.state === 'fulfilled') cb(suc)(this.val) else if (this.state === 'rejected') cb(err)(this.val) else { this.onFulfilled.push(cb(suc)) this.onRejected.push(cb(err)) } }) } }手写bind/call/bind
# call Function.prototype.myCall = function(ctx, ...args) { ctx = ctx || window ctx.fn = this const res = ctx.fn(...args) delete ctx.fn return res } # apply Function.propotype.myApply = function(ctx, args = []) { ctx = ctx || window ctx.fn = this const res = ctx.fn(...args) delete ctx.fn return res } # bind(返回新函数) Function prototype.myBind = function(ctx, ...args1) { const fn = this return function(...args2) { return fn.myCall(ctx, ...args1, ...args2) } }数组去重、flat扁平化
# 数组去重new Set function unique(arr){ return [...new Set(arr)] } # flat 扁平化(无限层级) function flat(arr){ return arr.reduce((pre,cur) => pre.concat(Array.isArray(cur) ? flat(cur) :cur),[]) }new实现
const myNew = (fn, ...args) => { const obj = object.create(Fn.prototype) const res = Fn.apply(obj, args) return typeof res === 'object' && res !== null ? res : obj }instanceOf
const myInstanceof = (left, right) => { let proto = Object.getPrototypeOf(left) while(proto) { if(proto === right.prototype) return true proto = Object.getPrototypeOf(proto) } return false }发布订阅模式
class EventBus{ constructor() { this.events = {} } on(type, fn){ if(! this.events[type].push(fn)) } emit(type, ...args) { this.events[type]?.forEach(fn => fn(...srgs))) } off(type, fn) { if(!this.events[type]) return this.events[type] = this.events[type].filter(item => item !== fn) } }简易Ajax
function ajax({ url, method = 'GET', data }) { return new Promise((res, rej) => { const xhr = new XMLHttpRequest() let params = '' if (data) params = new URLSearchParams(data).toString() let reqUrl = url if (method.toUpperCase() === 'GET' && params) reqUrl += '?' + params xhr.open(method, reqUrl) if (method.toUpperCase() !== 'GET') { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') } xhr.onload = () => xhr.status >= 200 && xhr.status < 300 ? res(xhr.response) : rej(xhr.statusText) xhr.onerror = () => rej('请求失败') xhr.send(method.toUpperCase() === 'GET' ? null : params) }) }