Es6_proxy习题讲解
概述
这是对于es6中的proxy部分中的一道题做讲解,因为其晦涩难懂,所以单独抽出来做解释,方便以后复习的时候能快速的过,而不用重新想破脑袋。
解析
var pipe = function (value) {
var funcStack = [];
var oproxy = new Proxy({} , {
get : function (pipeObject, fnName) {
if (fnName === 'get') {
return funcStack.reduce(function (val, fn) {
return fn(val);
},value);
}
funcStack.push(window[fnName]);
return oproxy;
}
});
return oproxy;
}
var double = n => n * 2;
var pow = n => n * n;
var reverseInt = n => n.toString().split("").reverse().join("") | 0;
pipe(3).double.pow.reverseInt.get; // 63
上述代码可以分成三部分,分别是代理部分,函数定义部分,和调用部分,我将针对这三部分按照最能让人理解的顺序进行讲解。
函数定义部分
var double = n => n * 2;
var pow = n => n * n;
var reverseInt = n => n.toString().split("").reverse().join("") | 0;
double和pow函数意思很明确,不需要过多的解释,但是reverseInt函数可以稍微解释一下。
reverseInt函数做了两件事情。第一,将字符串反转,第二,将字符串类型变成数字类型。
其中|0
起的作用就是将字符串类型转成数字类型。
代理部分
var pipe = function (value) {
var funcStack = [];
var oproxy = new Proxy({} , {
get : function (pipeObject, fnName) {
if (fnName === 'get') {
return funcStack.reduce(function (val, fn) {
return fn(val);
},value);
}
funcStack.push(window[fnName]);
return oproxy;
}
});
return oproxy;
}
首先,pipe是一个函数,我们调用pipe函数的时候会传入一个值value,最终函数调用的返回值是一个代理对象oproxy。
在pipe函数中我们定义了一个数组funcStack,用于存放我们函数定义部分定义的函数,这里需要注意一个问题,数组funcStack不是栈而是数组,例如funcStack.push(1,2,3)
,我们输出的funcStack数组值为[1,2,3]
,并不是[3,2,1]
。这里做出说明是因为涉及到后面的函数调用顺序的问题,因此特意说明一下。
代理对象oproxy,它给一个空对象 {} 设置了代理,其代理逻辑为,若是调用代理对象的属性名不为 "get" ,则执行下面的代码。
funcStack.push(window[fnName]);
return oproxy;
window[fnName]
根据字符串 fnName 来获取全局对象中具有相应名称的函数,并将其push到数组funcStack中,然后返回代理对象oproxy。
若是调用代理对象的属性名为 "get" ,则执行下面的代码。
return funcStack.reduce(function (val, fn) {
return fn(val);
},value);
funcStack.reduce
方法中回调函数function (val, fn) {return fn(val);}
以value作为初始值赋值给val,fn为当前数组funcStack中正在调用的值(因为数组funcStack中全为函数,所以相当于调用函数),然后执行fn(val)
所得的值赋值给累加器val用于下一轮的调用。
调用部分
pipe(3).double.pow.reverseInt.get;//63
综上所述,调用部分做的事情就是,以3作为初始值,分别调用double函数、pow函数和reverseInt函数,前一轮函数计算的值用在后一轮函数的计算之上,最终得出结果。
计算过程如下:
- double(3) = 6
- pow(6) = 36
- reverseInt(36) = 63