1、Object.defineProperty
1)Object.defineProperty 的设计初中不是为了监听对象中属性变化的,而是为了定义访问属性描述符
。
2)Object.defineProperty 的缺点:
① 一次监听太多的时候,不是很友好;
② 新增、删除的时候,他是无能为力的;
③ 会修改原对象中的属性。
const obj = {
name: "里斯",
age: 16
};
/**
* 监听某个属性
*/
/*
Object.defineProperty(obj, "name", {
set(v) {
console.log(v);
console.log("监听到 set");
},
get() {
console.log("监听到 get");
}
});
*/
/**
* 监听所有的属性
*/
Object.keys(obj).forEach(key => {
console.log(key);
let value = obj[key];
Object.defineProperty(obj, key, {
set(v) {
console.log(`监听到属性 ${key},被 set 为 ${v}`);
value = v;
},
get() {
console.log(`监听到属性 ${key} get`);
return value;
}
});
});
obj.name = "哈哈哈";
console.log(obj.name);
2、Proxy
在ES6中,新增了一个Proxy 类
,这个类从名字就可以看出来,是用于帮助我们创建一个代理的,也就是说,如果我们希望监听一个对象的相关操作,那么我们可以先创建一个代理对象 ( Proxy 对象),之后对该对象的所有操作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行哪些操作。
1)对象的监听
2)函数调用的监听
注:函数也是一个对象。
function fun() {
console.log("哈哈哈");
}
const objProxy = new Proxy(fun, {
/**
* 拦截对函数的调用的捕获器
* @param target target new Proxy 所代理的 obj(监听的对象)
* @param thisArg 调用函数时绑定的 this 值
* @param argArray 调用函数时传递的参数列表
*/
apply(target, thisArg, argArray) {
console.log("对 fun 函数进行了 apply 的调用。");
// 调用原始函数,并在其结果前后添加一些内容
target.apply(thisArg, argArray)
},
/**
* 监听 class 时的捕获器
* @param target target new Proxy 所代理的 obj(监听的对象)
* @param argArray new fun() 时传入的参数,例:new fun(1, 2, ...rest)
* @param newTarget 被调用的构造函数。在这里,newTarget 就是 objProxy 本身,因为 objProxy 是一个函数代理
*/
construct(target, argArray, newTarget) {
console.log("对 fun 函数进行了 construct 的调用。");
return new target(...argArray)
}
});
objProxy.apply();
new objProxy();