有没有办法使用 Javascript ES6 代理来监视对象方法

有没有可能,给定以下对象


let target = {

 foo:0,

 result:[],

 bar(){

   //some code

 }

}

然后将所述对象包装在Proxy()


let handler = {

  get(){

    // code here

  },

  apply(){

    // code here

   }

 }


 target = new Proxy(target,handler);

捕获调用bar()并将结果保存到results:[]?


我已经尝试了几次


let target = {

    called:0,

    results:[],

    foo(bar){

        return bar;

    },

}


let handler = {

    get(target,prop){

        console.log('Get Ran')

        return target[prop];

    },

    apply(target,thisArg,args){

        console.log('Apply Ran')

        // never runs

    }

}


target = new Proxy(target,handler);

target.foo();


此代码错过了 [[ apply ]] 但捕获了 [[ get ]] (如果内存服务,对象方法调用作为两个操作完成,[[ get ]] [[ apply ]])


let target = {

    called:0,

    results:[],

    foo(bar){

        return bar;

    },

}


let handler = {

    get(target,prop){

        return target[prop];

    },

    apply(target,thisArg,args){

        let product = target.apply(thisArg,args)

        return product;

    },

}


let prox = new Proxy(target.foo,handler);

    console.log(prox('hello'));

如果我改为将对象方法包装在代理中,它会捕获 [[ apply ]] 但我会丢失对原始对象( this )的引用,因此无法访问结果数组


我还尝试将方法代理嵌套在对象代理中。


有什么想法吗 ?


慕妹3146593
浏览 99回答 1
1回答

墨色风雨

根据规格如果其 [[ProxyTarget]] 内部槽的初始值是具有 [[Call]] 内部方法的对象,则代理外来对象仅具有 [[Call]] 内部方法。所以如果目标是一个function(new Proxy(() => 'hello', { apply: () => console.log('catched') }))() // 'catched反过来,如果目标没有调用方法,则没有代理try {&nbsp; (new Proxy({}, { apply: () => console.log('catched') }))() // throws} catch (e){ console.log('e', e.message)}所以提示可能是代理 [get] 而不是返回值(作为函数bar,代理该值以捕获最终调用const p = new Proxy(&nbsp; { results: [], bar: () => { console.log('rywhite') } }, {&nbsp; get: (target, prop) => {&nbsp; &nbsp; if (prop !== 'bar') return target[prop]&nbsp; &nbsp; return new Proxy (target.bar, {&nbsp; &nbsp; &nbsp; apply () {&nbsp; &nbsp; &nbsp; &nbsp; target.results.push('what')&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })&nbsp; }})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{&nbsp; const target = { results: 0, bar: () => { console.log('rywhite') } }&nbsp; const p = new Proxy(&nbsp; &nbsp; target, {&nbsp; &nbsp; get: (() => {&nbsp; &nbsp; &nbsp; const barProxy = new Proxy (target.bar, {&nbsp; &nbsp; &nbsp; &nbsp; apply () {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; target.results++&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; return (target, prop) => {&nbsp; &nbsp; &nbsp; &nbsp; if (prop !== 'bar') return target[prop]&nbsp; &nbsp; &nbsp; &nbsp; return barProxy&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })()&nbsp; })&nbsp; console.time('go')&nbsp; for (let i = 0; i < N; ++i) { p.bar() }&nbsp; console.timeEnd('go')&nbsp; console.log('res', p.results)}{&nbsp; const p = new Proxy(&nbsp; &nbsp; { results: 0, bar: () => { console.log('rywhite') } }, {&nbsp; &nbsp; &nbsp; get: (target, prop) => {&nbsp; &nbsp; &nbsp; &nbsp; if (prop !== 'bar') return target[prop]&nbsp; &nbsp; &nbsp; &nbsp; return new Proxy (target.bar, {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; apply () {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; target.results++&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })&nbsp; console.time('neweverytime')&nbsp; for (let i = 0; i < N; ++i) { p.bar() }&nbsp; console.timeEnd('neweverytime')&nbsp; console.log('res', p.results)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript