鍍金池/ 問答/HTML/ ES6 Proxy apply的疑問

ES6 Proxy apply的疑問

var twice = {
    apply (target, ctx, args) {
        return Reflect.apply(...arguments) * 2;
    }
};
function sum (left, right) {
    return left + right;
};

var proxy = new Proxy(sum, twice);
console.log(proxy(1, 2))

apply方法攔截函數(shù)的調(diào)用、call和apply操作。
想了蠻久,始終沒懂執(zhí)行流程。

回答
編輯回答
艷骨

攔截器中的Reflect.apply應(yīng)該相當(dāng)于調(diào)用sum.bind(ctx)ctx是調(diào)用時(shí)的上下文對(duì)象,這里是undefined
這樣你調(diào)用proxy(1,2)的返回值就相當(dāng)于,Reflect.apply(...arguments)*2,也就是sum.bind(undefined)(1,2)。

阮大大有寫到:

Proxy 用于修改某些操作的默認(rèn)行為,等同于在語(yǔ)言層面做出修改,所以屬于一種“元編程”(meta programming),即對(duì)編程語(yǔ)言進(jìn)行編程。
Proxy 可以理解成,在目標(biāo)對(duì)象之前架設(shè)一層“攔截”,外界對(duì)該對(duì)象的訪問,都必須先通過這層攔截,因此提供了一種機(jī)制,可以對(duì)外界的訪問進(jìn)行過濾和改寫。

我個(gè)人理解是,本來你能直接達(dá)到目標(biāo)(直接調(diào)用sum),而現(xiàn)在你想訪問對(duì)象會(huì)經(jīng)過一個(gè)攔截層,你可以在調(diào)用前修改參數(shù),也可以在調(diào)用后修改返回值(比如本例的*2)。
攔截器類似元編程,相當(dāng)于修改語(yǔ)言特性的語(yǔ)法,比如本例就是對(duì)函數(shù)的apply機(jī)制進(jìn)行修改,其他代理如get、set等相當(dāng)于對(duì)對(duì)象的讀寫特性進(jìn)行了修改,表面上看就好像語(yǔ)言特性被修改了。
看下這兩個(gè)例子應(yīng)該就能明白如何用Proxy來代理一個(gè)函數(shù):

function sum(left, right) {
  return (this.x || left) + right;
}
var twice = {
  apply(target, ctx, args) {
    console.log(ctx == obj);
    return Reflect.apply(...arguments) * 2;
  },
};

var proxy = new Proxy(sum, twice);
let obj = { test: "test", proxy, x: 33 };
console.log(obj.proxy(1, 2));
//true
//70
//可見ctx為執(zhí)行環(huán)境this

var twice_changeParams = {
  apply(target, ctx, args) {
    args[1] = args[1] + 5;
    return Reflect.apply(...arguments) * 2;
  },
};
proxy = new Proxy(sum, twice_changeParams);
console.log(proxy(1, 2));
// 16
//16為sum(1,(2+5))*2 分別對(duì)輸入和輸出進(jìn)行了攔截
//這就是攔截器的含義
2018年3月11日 03:40