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)
}
添加回答
舉報