版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m_review/article/details/90443242
Proxy
含义
在目标对象之前架设一层 拦截
,访问该对象时必须经过这层拦截,对外界的访问进行过滤和改写
let obj = new Proxy(
{},
{
get: function(target, key, receiver) {
console.log(`get ${key}`);
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
console.log(`set ${key}`);
return Reflect.set(target, key, value, receiver);
}
}
);
obj.count = 1; // set count
++obj.count; // get count set count
api
var proxy = new Proxy(target, handler);
target
: 所要拦截的目标对象
handler
: 定制拦截操作
支持 13 个拦截操作
set、get、has、deleteProperty、apply、construct …
具体参考:http://es6.ruanyifeng.com/#docs/proxy#Proxy-实例的方法
Proxy.revocable()
Proxy.revocable()
返回一个可取消的 Proxy 实例
// revoke: 取消 Proxy 实例
let { proxy, revoke } = Proxy.revocable({}, {});
proxy.foo = 123;
proxy.foo; // 123
revoke();
proxy.foo; // TypeError: Revoked
当执行 revoke
函数之后,再访问 Proxy 实例,就会抛出一个错误。
this 问题
在 Proxy 代理的情况下,目标对象内部的 this 关键字会指向 Proxy 代理。
let target = {
m: function() {
console.log(this === proxy);
}
};
let handler = {};
let proxy = new Proxy(target, handler);
target.m(); // false
proxy.m(); // true
web 服务的客户端
Proxy 对象可以拦截目标对象的任意属性,这使得它很合适用来写 Web 服务的客户端:
const service = createWebService("http://example.com/data");
service.employees().then(json => {
const employees = JSON.parse(json);
// ···
});
尝尽:Proxy 可以拦截 service 对象的任意属性,所以不用为每一种数据写一个适配方法,只要写一个 Proxy 拦截就可以了。
function createWebService(baseUrl) {
return new Proxy(
{},
{
get(target, propKey, receiver) {
return () => httpGet(baseUrl + "/" + propKey);
}
}
);
}
使用 Proxy 实现观察者模式
观察者模式
:函数自动观察数据对象,一旦数据发生变化,函数就会自动执行
// person 观察目标
const person = observable({
name: "kk",
age: 12
});
// print 观察者
function print() {
console.log(`打印:姓名 ${person.name}, 年龄 ${person.age}`);
}
observe(print);
person.name = "lisi";
使用 Proxy 写一个观察者模式的最简单实现,即实现 observable
和 observe
这两个函数。
思路:observable 函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj =>
new Proxy(obj, {
set
});
function set(target, key, value, receiver) {
// 拦截赋值操作
const result = Reflect.set(target, key, value, receiver);
// 触发各个观察者
queuedObservers.forEach(observer => observer());
return result;
}
Reflect
作用
-
从 Reflect 对象上拿语言内部的方法
-
修改某些 Object 方法的返回结果
比如:在无法定义属性时,Object 会抛出一个错误,Reflect 会返回 false
-
让 Object 命令式操作都变成函数行为
// 老写法 "assign" in Object; // true // 新写法 Reflect.has(Object, "assign"); // true
-
Reflect 对象的方法与 Proxy 对象的方法一一对应
Reflect 对象的 13 个静态方法
get、set、has、deleteProperty、apply、construct …