1. Proxy
说明:Proxy可以理解成在目标对象架设一层拦截器,外界访问内部的变量都必须经过这一层,可以对外界的访问进行过滤和改写。
1.1例子:
const proxy=new Proxy(target,handler)
说明:Proxy对象的用法,都是上面这样的形式,不同的只是handler参数写法不同。 target表示拦截的对象,handler参数也是对象,用来定制拦截行为。
1.2例子:
const proxy1 = new Proxy({},{get: function (target, propkey) {return 35;},});console.log(proxy1.item); //35console.log(proxy1.good); //35
说明:配置对象中有一个get方法,用来拦截对目标对象属性的访问请求。get方法有两个参数分别是目标对象和所要访问的属性。
注意:注意:要是的Proxy起作用,必须针对Proxy实例进行操作,而不是针对目标对象(空对象)进行操作。
1.3例子
说明:如果没有设置任何拦截,那么等同于通向源对象
const obj1 = {name: "李四",};const proxy2 = new Proxy(obj1, {});console.log(proxy2.name); //李四
1.4例子
说明: Proxy实例也可以作为其他对象的原型对象
const proxy3 = new Proxy({},{get: function (a, b, c) {return 35;},});const obj2 = Object.create(proxy3);console.log(obj2.age); //35
注意: 同一个拦截器函数,可以设置拦截多个操作。
2.常见的Proxy支持的拦截操作
- get(target,propkey,receiver)
- set(target,propkey,value,receiver)
- has(target,propkey)
- deleteProperty(target,propKey)
- ownKeys(target) //拦截Object.keys(),for...in 循环
3.Proxy实例的方法
3.1get()
说明:get()用于拦截某个属性的读取,可以接受三个参数,为目标对象,属性,proxy实例本身
const p1 = new Proxy({ name: "张三" },{get: function (target, propkey) {if (propkey in target) {return target[propkey];} else {// throw new Error(`对象中没有${propkey}这个属性`)}},});console.log(p1.name); //张三console.log(p1.age); //对象中没有age这个属性
3.2 set()
说明:set()用来拦截某个属性的赋值操作,可以接受四个参数,target,key,value,proxy实例本身。
const adult = {name: "张三",age: 18,};const p2 = new Proxy(adult, {set: function (target, key, value) {if (key === "age") {if (Number.isInteger(value)) {console.log(value);if (value < 100) {target[key] = value;} else {throw Error("年龄值大于100");}} else {throw Error("年龄值类型错误");}}},});p2.age=600 //年龄值大于100p2.age="年龄" //年龄值类型错误
说明:每当对象发生变化时,会自动更新DOM。
规定:对象上面设置内部属性,属性名的第一个字符使用下划线开头,表示这些属性不应该被外部使用。结合get和set方法,就可以做到防止这些内部属性被外部读写。
3.3apply()
说明:apply方法用于拦截函数的调用,call和apply操作,apply方法可以接受三个参数,target,this(目标对象的上下文对象),args(目标对象的参数数组)。
const target1 = function () {return `我是一个target1函数`;};const p3 = new Proxy(target1, {apply: function () {return `我是一个代理函数`;},});console.log(p3()); //我是一个代理函数
3.3.1例子:
const double = {apply(target, contextThis, args) {console.log(Reflect.apply(...arguments));},};const fun1 = function (a, b) {return a + b;};const p4 = new Proxy(fun1, double);p4(1, 2); //3
3.4has()
说明:拦截HasProperty操作,典型操作in运算符。
const obj3 = { name: "张三", _age: 25 };const p5 = new Proxy(obj3, {has(target, key) {if (key[0] === "_") {throw Error("你没有这个权限")} else {return console.log(true);}},});// '_age' in p5 //你没有这个权限name in p5 //true
说明:如果原对象的属性名的第一个字符是下划线,proxy.has()就会返回你没有这个权限。
3.5construct()
说明:construct()方法用于拦截new命令,下面是拦截对象的写法。target:目标对象,args构造函数的参数数组,newTarget:创造实例对象,new命令作用的构造函数。
const p6 = new Proxy(function () { }, {construct(target, args, newTarget) {console.log(...args); //2return { value: 52 }}})console.log(new p6(2).value); //52
注意:由于construct()拦截的是构造函数,所以它的目标对象必须是函数,否则就会报错。
3.6ownKeys()
说明:ownKeys()方法用来拦截对象自身属性的读取操作。
const p7 = new Proxy({ name: "张三", age: "18" }, {ownKeys(target) {return ["name"]}})console.log(Object.keys(p7)); //name
注意:ownKeys()方法返回的数组之中,必须包含原对象的所有属性,且不能包含多余的属性,否则报错。