ES6的新语法:鸣谢
https://www.villainhr.com/page/2016/07/29/%E8%B6%85%E5%A5%BD%E7%94%A8%E7%9A%84es6%20proxy
https://blog.csdn.net/qq_30100043/article/details/53443017
语法格式:
// @param {Object} target 用来被代理的对象
// @param {Object} handler 用来设置代理的对象
var proxy = new Proxy(target, handler);
执行原理:
就是通过handler中,重载的方法,阻止掉获取target的内容. 其,最常用的地方,就在于它的一个middleware的特性. 因为,在js中,经常会对数据格式进行验证. 这里,就可以使用proxy来进行替换. 所以, proxy经常是用来处理数据的接口操作的。
Get与Set方法:(读取与赋值)
get方法示例:
get(target,property)中的target, property分别代表什么?
target:被拦截对象
,property:属性
- get申明的两种方法:
var person = {
name: " 张三 "
};
var proxy = new Proxy(person, {
// target 即是 person,property 即是 "name"
get: function(target, property) {
if(property in target) {
return target[property];
} else {
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
});
proxy.name // " 张三 "
proxy.age // 抛出一个错误
const target = {
name: 'Billy Bob',
age: 15
};
const handler = {
// @param {Object} target 就是被proxy的对象
// @param {String} key 通过proxy 访问的键名
// @param {proxy} proxy 代理过后传递的对象
get(target, key, proxy) {
const today = new Date();
console.log(`GET request made for ${key} at ${today}`);
// Reflect实际上,是Object的一个替代
return Reflect.get(target, key, proxy);
// Reflect.get(target,name,receiver) *
// Reflect.set(target,name,value,receiver) *
}
};
const proxy = new Proxy(target, handler);
receiver是什么?
var target = {
get b(){return this.a},
a:1,
}
var receiver = {
a:2
}
// 如果设置了receiver, 并且target中设置了b的get 返回. 则将this替换为receiver
console.log(Reflect.get(target,"b",receiver));
// Reflect.get(target,"b",receiver) 相当于target.b;
>>> 2
set方法示例
// 对set方法也一样
var target = {
// 这里的this指的是receiver
set b(val){this.a=val},
a:1,
}
var receiver = {
a:2
}
console.log(Reflect.set(target,"b",4,receiver)); // true
console.log(receiver.a); //4
console.log(target.a); //1
has方法(应对迭代)
has方法用来拦截HasProperty操作, 即判断对象是否具有某个属性时, 这个方法会生效。 典型的操作就是in运算符。
下面的例子使用has方法隐藏某些属性, 不被in运算符发现。
var handler = {
has(target, key) {
if(key[0] === '_') {
return false;
}
return key in target;
}
};
var target = {
_prop: 'foo',
prop: 'foo'
};
var proxy = new Proxy(target, handler);
'_prop' in proxy // false
最后解释一下这个代码:
const x=new Proxy([l=1],{has:a=>l--});
if(('a' in x)&&!('a' in x)){
console.log('WIN111');
}
初始化一个数组[1],在第一次遍历时如果有请求x.a(拦截器对x的a属性有用)则返回1,第二次返回 0