代理模式的作用
被代理对象不能直接访问,需要通过代理。
标准代理模式
class Singer {
name: string
constructor(name: string) {
this.name = name
this.prepareMusic()
}
singSong() {
console.log('Singing...')
}
private prepareMusic() {
console.log('Preparing...')
}
}
class Agent {
singer: Singer
constructor(name: string) {
this.singer = new Singer(name)
}
singSong(cnt: number) {
while(cnt--) this.singer.singSong()
}
}
const agent = new Agent('Jay')
agent.singSong(3)
// Preparing...
// Singing...
// Singing...
// Singing...
代理模式的应用
DOM事件代理
- 将事件绑定到父容器上
- 适合子元素数量不确定的场景(如图片瀑布流)
Proxy语法
跟踪属性(Vue3 数据响应式)
const city = {
name: '西安'
}
const proxy = new Proxy(city, {
get(target, key) {
console.log('get...')
return Reflect.get(target, key)
},
set(target, key, val) {
console.log('set...', val)
return Reflect.set(target, key, val)
}
})
proxy.name = '上海'
console.log(proxy.name)
隐藏属性
const city = {
name: '西安'
}
const hiddenProps = ['name']
const proxy = new Proxy(city, {
get(target, key) {
if(hiddenProps.includes(key as string)) return undefined
return Reflect.get(target, key)
},
set(target, key, val) {
if(hiddenProps.includes(key as string)) return false
return Reflect.set(target, key, val)
},
has(target, key) {
if(hiddenProps.includes(key as string)) return false
return Reflect.has(target, key)
}
})
记录实例
class City {
name: string
constructor(name: string) {
this.name = name
}
}
const cityList = new Set()
const proxy = new Proxy(City, {
construct(...args) {
const city = Reflect.construct(...args)
cityList.add(city)
return city
}
})