1. Proxy的设计初衷在一些前端框架中,常常需要监听数据变化,页面进行响应。为了监听对象的变化,需要对对象的 *** 作进行捕获。本文着重介绍ES6中Proxy代理对象的使用,以及涉及到的映射对象Reflect使用
为了监听对象的属性 *** 作,在ES6之前一般借助于Object.defineProperty来实现,但有以下缺点
Object.defineProperty设计初衷并不是要监听属性对于新增属性、删除属性监听不到将原来对象修改了(数据属性描述符–》存取属性描述符),不应该改变原始对象在ES6中,新增了一个Proxy类,Proxy翻译为“代理”,是用于帮助我们创建一个代理的:
如果我们希望监听一个对象的相关 *** 作,那么我们可以先创建一个代理对象(Proxy对象)之后对该对象的所有 *** 作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行哪些 *** 作 2. Proxy类用法const objProxy = new Proxy(obj, handler);
其中参数obj是要代理的原始对象,handler是捕获器对象,包含13中捕获器方法
// 1 原始对象
const obj = { name: "xs", age: 18 };
console.log(obj);
// 2 代理对象
// new Proxy(target, handler)第一个参数为要代理的目标对象,第二个为对对象 *** 作的监听处理对象
const objProxy = new Proxy(obj, {});
console.log(objProxy);
浏览器中打印如下:可以清楚看到第一个是对象类型Object,第二个是Proxy类型对象
那么,代理对象如何监听我们的 *** 作呢,就需要用到捕获器,Proxy中有13种捕获器
创建Proxy对象的第二个入参为handler对象,里面可以设置13中捕获器方法,但最常用的只有4种:get
set, has, deleteProperty
const obj = {
name: "xs",
age: 18,
};
const objProxy = new Proxy(obj, {
// 获取值 捕获器 target:obj,
get(target, key) {
console.log(`监听到对象的${key}属性被访问了`, target);
return target[key];
},
// 设置值 捕获器
set(target, key, newValue) {
console.log(`监听到对象的${key}属性被赋值了`, target);
target[key] = newValue;
},
// has 捕获器
has(target, key) {
console.log(`监听到对象的${key}属性in *** 作`, target);
target.has(key)
},
// delete 捕获器
deleteProperty(target, key) {
console.log(`监听到对象的${key}属性删除 *** 作`, target);
delete target[key];
},
});
调用
console.log(objProxy.name); // get
objProxy.name = 'kobe'; // set
console.log('name' in obj) // has
delete obj.name // deleteProperty
2种与函数相关的捕获器(了解)
apply 捕获函数的apply方法construct 捕获函数作为构造函数
// 1 创建函数对象
function foo() {
console.log(this);
}
// 2 创建函数代理对象
const fooProxy = new Proxy(foo, {
// 设置apply捕获器
apply(target, thisArg, argArray) {
console.log(`监听函数${target.name}的apply *** 作`);
target.apply(thisArg, argArray);
},
// 设置构造函数捕获器
construct(target, argArray) {
console.log(`监听函数${target.name}的construct *** 作`);
return new target(...argArray);
}
});
// 3 调用代理对象
fooProxy(); // 不会被捕获
fooProxy.apply({ name: "xs" }, ["dsh", "dshjk"]); // 监听函数foo的apply *** 作
const f = new fooProxy(); // 监听函数foo的construct *** 作
4. Reflect映射对象
Reflect也是ES6中提出的一个新对象,字面意思是反射。(看着高大上,其实很简单)
简单认知:Reflect是Object的一个替身。Object.getOwnProperty()和Reflect.getOwnProperty()一样
Reflect中有13种方法,与Proxy一一对应
5. Proxy + Reflect配合使用
用Reflect替换代理对象捕获器中直接对原对象进行 *** 作
const obj = {
name: "xs",
age: 18,
};
const objProxy = new Proxy(obj, {
get(target, key, receiver) {
// receiver永远指向 Proxy 本身或者继承它的对象
return Reflect.get(target, key, receiver); // 语言内部获取,替代return target[key]
// Reflect中的receiver可以改变计算属性中 this 的指向
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver); //会返回一个布尔值,标志 *** 作是否成功 替代target[key] = newValue
},
});
objProxy.name = "kobe";
console.log(objProxy.name);
6. 总结
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)