1 回答

TA贡献1853条经验 获得超6个赞
根据规格
如果其 [[ProxyTarget]] 内部槽的初始值是具有 [[Call]] 内部方法的对象,则代理外来对象仅具有 [[Call]] 内部方法。
所以如果目标是一个function
(new Proxy(() => 'hello', { apply: () => console.log('catched') }))() // 'catched
反过来,如果目标没有调用方法,则没有代理
try {
(new Proxy({}, { apply: () => console.log('catched') }))() // throws
} catch (e){ console.log('e', e.message)}
所以提示可能是代理 [get] 而不是返回值(作为函数bar,代理该值以捕获最终调用
const p = new Proxy(
{ results: [], bar: () => { console.log('rywhite') } }, {
get: (target, prop) => {
if (prop !== 'bar') return target[prop]
return new Proxy (target.bar, {
apply () {
target.results.push('what')
}
})
}
})
p.bar // nothing bud'
p.bar(); console.log('res', p.results)
p.bar(); console.log('res', p.results)
p.bar(); console.log('res', p.results)
编辑:注意:不必每次都创建新代理
在下面的代码中,返回相同的代理大约快两倍
const N = 1e6
{
const target = { results: 0, bar: () => { console.log('rywhite') } }
const p = new Proxy(
target, {
get: (() => {
const barProxy = new Proxy (target.bar, {
apply () {
target.results++
}
})
return (target, prop) => {
if (prop !== 'bar') return target[prop]
return barProxy
}
})()
})
console.time('go')
for (let i = 0; i < N; ++i) { p.bar() }
console.timeEnd('go')
console.log('res', p.results)
}
{
const p = new Proxy(
{ results: 0, bar: () => { console.log('rywhite') } }, {
get: (target, prop) => {
if (prop !== 'bar') return target[prop]
return new Proxy (target.bar, {
apply () {
target.results++
}
})
}
})
console.time('neweverytime')
for (let i = 0; i < N; ++i) { p.bar() }
console.timeEnd('neweverytime')
console.log('res', p.results)
}
添加回答
举报