JavaScript(八股试题004):Proxy 能监听到对象中“对象类型属性”的引用和变化吗?
·
题意解析
通过 Proxy 的 递归代理 技术,我们能够拦截对象内部嵌套对象的属性访问(get)和属性修改(set)。
代码解析
const obj = {
nestedObj: { foo: 'bar' }
}
const handler = {
get(target, prop, receiver) {
const value = Reflect.get(target, prop, receiver) // 1. 获取属性值
// 2. 如果属性值是非null对象,则再次用 Proxy 包装 → 递归代理
if (typeof value === 'object' && value !== null) {
return new Proxy(value, handler)
}
console.log('get', prop, target[prop])
return value
},
set(target, property, value) {
console.log(`Setting property '${property}' to '${value}'`)
target[property] = value // 赋值
return true
}
}
const proxyObj = new Proxy(obj, handler)
// 访问嵌套对象的属性
console.log(proxyObj.nestedObj.foo)
// 修改嵌套对象的属性
proxyObj.nestedObj.foo = 'baz'
运行结果(概念上)
get foo bar
Setting property 'foo' to 'baz'
说明:
- 当我们访问
proxyObj.nestedObj时,get 拦截触发。 - 由于
nestedObj是对象,get 内部又创建了一个新的 Proxy,实现递归代理。 - 访问
nestedObj.foo时能进入拦截器,修改时也会被 set 捕获。
原理图(Mermaid)
流程说明:
- 第一层 Proxy 负责拦截
obj的直接属性访问。 - 如果访问的是对象(
nestedObj),就返回一个新的 Proxy 来包裹这个对象。 - 于是嵌套对象也有自己的 Proxy 拦截器,从而实现了对内部对象的监听。
刷题笔记
- 要点1:默认
Proxy只拦截它直接代理的对象。要监听嵌套对象,必须在get中递归创建新的 Proxy。 - 要点2:
typeof value === 'object' && value !== null是判断是否为对象(包括数组)。 - 要点3:这种方式会在每次访问嵌套对象时创建新 Proxy,要注意性能和内存消耗。
- 要点4:适合监听较深层次的属性变化(比如做响应式系统)。
更多推荐
所有评论(0)