// 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);