proxy
我们在设置代理的时候我们会经常用到这个方法,那么它究竟是一个怎么样的方法呢?
var obj = new Proxy(
{},
{
get: function(target, propKey, receiver) {
console.log(`getting ${propKey}!`);
return Reflect.get(target, propKey, receiver);
},
set: function(target, propKey, value, receiver) {
console.log(`setting ${propKey}!`);
return Reflect.set(target, propKey, value, receiver);
},
}
);
obj.count = 1;
++obj.count;
obj.count;
通过打印我只得到了setting,getting,setting也就是说再这分别是两次设置,即把它拿到的属性覆盖在返回
而在阮一峰的es6里面对其的解释是
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程
那么我们对get和set的属性都进行打印
var obj = new Proxy(
{},
{
get: function(target, propKey, receiver) {
console.log(`getting ${propKey}!`, target, propKey, receiver);
return Reflect.get(target, propKey, receiver);
},
set: function(target, propKey, value, receiver) {
console.log(`setting ${propKey}!`, target, propKey, receiver);
return Reflect.set(target, propKey, value, receiver);
},
}
);
obj.count = 1;
++obj.count;
obj.count; //这里是我踩的一个坑只有前面两个会发现有两个settting但是只有一个getting导致只出现一个count:1
控制台结果
这里get的属性是 依次为目标对象、属性名和 proxy 实例本身 set的属性是依次为目标对象、属性名、属性值和 Proxy 实例本身 在Proxy里面还有很多方法例如
get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy[‘foo’]。
set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。
has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for…in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(…args)。
常用的是get和set
通过以上我们发现Proxy是对传进来的目标值进行拦截,然后再加工的一个属性和工厂模式很类似
通过这些我们可以实现一个链式调用,实现一个自身加6然后乘上加过后的自己再反转代码如下
var p = function(value) {
var result = [];
var start = new Proxy(
{},
{
get: function(pObject, fnName) {
if (fnName === "get") {
return result.reduce((val, fn) => {
return fn(val);
}, value);
}
result.push(window[fnName]);
return start;
},
}
);
return start;
};
var double = n => n * 6;
var pow = n => n * n;
var reverseInt = n =>
n
.toString()
.split("")
.reverse()
.join("") | 0;
let a = p(4).double.pow.reverseInt.get;