实现方法

72 阅读2分钟

// vue3 响应式用的方法 let data = [{ name: '顺利', age: 28 }] const obj = new Proxy(data, { get(target, key, receiver) { if (Reflect.ownKeys(target).includes(key)) { console.log('get', key); } const result = Reflect.get(target, key, receiver) return result }, set(target, key, value, receiver) { const result = Reflect.set(target, key, value, receiver); console.log('set', key, value); return result }, deleteProperty(target, key, value, receiver) { const result = Reflect.deleteProperty(target, key, value, receiver); return result }, }) // console.log('obj',obj); // console.log('obj.name',); // Object.defineProperty // obj.name='wangchongzhuo' // obj.push(1)

// symbol

// bind 实现原理 function myBind(context, bindArgs) { return (...args) => { // 拼接参数 const newArgs = bindArgs.concat(args) return this.apply(context, newArgs) } } // 实现call this指向调用我的函数,把this在要修改的this(context)中执行就修改了函数的this,执行后删除防止污染 最后返回执行结果 function myCall(context, ...args) { if (context === null) context = globalThis if (typeof context !== "object") context = new Object(context) const fnKey = Symbol() context[fnKey] = this const res = contextfnKey delete context[fnKey] return res } // 实现apply 同call一样只是参数不同 function myApply(context, args) { if (context === null) context = globalThis if (typeof context !== "object") context = new Object(context) const fnKey = 'ldkjfdk' context[fnKey] = this const res = contextfnKey delete context[fnKey] return res }

Function.prototype.myBind = myBind Function.prototype.myCall = myCall Function.prototype.myApply = myApply function adds() { return [...arguments].reduce((a, b) => { return a + b }, 0) } // adds.myApply({a:100},[1,3,5,10]) // adds.myCall({a:100},1,3,5) // let fns = adds.myBind({a:1000},[1,2,3,4,5,6])

// 自定义事件 class EventBus { events = {} onceEvents = {} constructor() { this.events = {} this.onceEvents = {} } on(type, fn) { const events = this.events if (events[type] == null) events[type] = [] events[type].push(fn) } once(type, fn) { const onceEvents = this.onceEvents if (onceEvents[type] == null) onceEvents[type] = [] onceEvents[type].push(fn) } off(type, fn) { if (!fn) { // 解绑所有事件 this.events[type] = [] this.onceEvents[type] = [] } else { // 解绑单个事件 const fnList = this.events[type] const onceFnList = this.onceEvents[type] if (fnList) { this.events[type] = fnList.filter(curFn => curFn !== fn) } if (onceFnList) { this.onceEvents[type] = onceFnList.filter(curFn => curFn !== fn) } } } emit(type, ...args) { const fnList = this.events[type] const onceFnList = this.onceEvents[type] if (fnList) { fnList.forEach(f => f(...args)) } if (onceFnList) { onceFnList.forEach(f => f(...args)) // once 执行一次就删除 this.onceEvents[type] = [] } } }

// const e = new EventBus() // function fn1(a, b) { console.log('fn1', a, b) } // function fn2(a, b) { console.log('fn2', a, b) } // function fn3(a, b) { console.log('fn3', a, b) } // e.on('key1', fn1) // e.on('key1', fn2) // e.once('key1', fn3) // e.on('xxxxxx', fn3) // e.emit('key1', 10, 20) // 触发 fn1 fn2 fn3 // e.off('key1', fn1) // e.emit('key1', 100, 200) // 触发 fn2

// LRU缓存 class LRUCache { len = 0 data = new Map() constructor(length) { if (length < 1) throw new Error('无效的 length') this.len = length } set(key, value) { const data = this.data if (data.has(key)) { data.delete(key) } data.set(key, value) if (data.size > this.len) { const delKey = data.keys().next().value data.delete(delKey) } } get(key) { const data = this.data if (!data.has(key)) return null const value = data.get(key) data.delete(key) data.set(key, value) return value } }
// 没有map实现LRU
class LRUCache2 { len = 0 data = {} dataLen = 0 dataHead = null dataTail = null constructor(length) { if (length < 1) throw new Error('无效的 length') this.len = length } get(key) { const data = this.data const curNode = data[key] if (curNode === null) return null if (curNode === this.dataTail) { return curNode.val } return curNode.val } set(key, val) { const data = this.data const curNode = data[key] || null if (curNode === null) { this.dataLen=this.dataLen+1 // 新增 const newNode = { key, val } data[key] = newNode let prevNode = this.dataTail || null if (prevNode !== null) { prevNode.next = newNode newNode.prev = prevNode } this.dataTail = newNode if(this.dataLen>this.len){ this.delete(this.dataHead.key) } if (this.dataLen <= 1) this.dataHead = newNode } else { // 修改 this.delete(key) this.set(key, val) } } delete(key) { this.dataLen=this.dataLen-1 const data = this.data const curNode = data[key] || null let prevNode=curNode.prev||null let nextNode=curNode.next||null if(prevNode){ if(nextNode){ prevNode.next=nextNode nextNode.prev=prevNode }else{ delete prevNode.next } }else{ this.dataHead = nextNode if(nextNode){ delete nextNode.prev } } delete data[key] } }

// 没有map实现LRU class LRUCache3 { length = 0 data = {} dataLength = 0 listHead = null listTail = null constructor(length) { if (length < 1) throw new Error('invalid length') this.length = length } moveToTail(curNode) { const tail = this.listTail if (tail === curNode) return const prevNode = curNode.prev const nextNode = curNode.next if (prevNode) { if (nextNode) { prevNode.next = nextNode } else { delete prevNode.next } } if (nextNode) { if (prevNode) { nextNode.prev = prevNode } else { delete nextNode.prev } if (this.listHead === curNode) this.listHead = nextNode } delete curNode.prev delete curNode.next if (tail) { tail.next = curNode curNode.prev = tail } this.listTail = curNode } tryClean() { while (this.dataLength > this.length) { const head = this.listHead if (head == null) throw new Error('head is null') const headNext = head.next if (headNext == null) throw new Error('headNext is null') delete headNext.prev delete head.next this.listHead = headNext delete this.data[head.key] this.dataLength = this.dataLength - 1 } } get(key) { const data = this.data const curNode = data[key] if (curNode == null) return null if (this.listTail === curNode) { return curNode.value } this.moveToTail(curNode) return curNode.value } set(key, value) { const data = this.data const curNode = data[key] if (curNode == null) { const newNode = { key, value } this.moveToTail(newNode) data[key] = newNode this.dataLength++ if (this.dataLength === 1) this.listHead = newNode } else { curNode.value = value this.moveToTail(curNode) } this.tryClean() } }

let lruCache = new LRUCache(3) // 深拷贝实现 function deepCopy(obj) { if (typeof obj !== 'object' || obj == null) return obj let target = {} if (obj instanceof Map) { target = new Map() obj.forEach((v, k) => { const v1 = deepCopy(v) const k1 = deepCopy(k) target.set(k1, v1) }) } if (obj instanceof Set) { target = new Set() obj.forEach(v => { const v1 = deepCopy(v) target.add(v1) }) } if (obj instanceof Array) { target = obj.map(item => deepCopy(item)) } for (const key in obj) { const val = obj[key] const val1 = deepCopy(val) target[key] = val1 } return target } let obj = { set: new Set([10, 20, 30]), map: new Map([['x', 10], ['y', 20]]), info: { city: '北京' }, fn: () => { console.info(100) } } let obj2 = deepCopy(obj) obj2.name = '4444444444444' console.log('obj', obj2); console.log('obj', obj);