1. Proxy
说明:Proxy可以理解成在目标对象架设一层拦截器,外界访问内部的变量都必须经过这一层,可以对外界的访问进行过滤和改写。
1.1例子:
javascript"> const proxy=new Proxy(target,handler)
说明:Proxy对象的用法,都是上面这样的形式,不同的只是handler参数写法不同。 target表示拦截的对象,handler参数也是对象,用来定制拦截行为。
1.2例子:
javascript"> const proxy1 = new Proxy(
{},
{
get: function (target, propkey) {
return 35;
},
}
);
console.log(proxy1.item); //35
console.log(proxy1.good); //35
说明:配置对象中有一个get方法,用来拦截对目标对象属性的访问请求。get方法有两个参数分别是目标对象和所要访问的属性。
注意:注意:要是的Proxy起作用,必须针对Proxy实例进行操作,而不是针对目标对象(空对象)进行操作。
1.3例子
说明:如果没有设置任何拦截,那么等同于通向源对象
javascript">const obj1 = {
name: "李四",
};
const proxy2 = new Proxy(obj1, {});
console.log(proxy2.name); //李四
1.4例子
说明: Proxy实例也可以作为其他对象的原型对象
javascript"> 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实例本身
javascript"> 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实例本身。
javascript"> 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 //年龄值大于100
p2.age="年龄" //年龄值类型错误
说明:每当对象发生变化时,会自动更新DOM。
规定:对象上面设置内部属性,属性名的第一个字符使用下划线开头,表示这些属性不应该被外部使用。结合get和set方法,就可以做到防止这些内部属性被外部读写。
3.3apply()
说明:apply方法用于拦截函数的调用,call和apply操作,apply方法可以接受三个参数,target,this(目标对象的上下文对象),args(目标对象的参数数组)。
javascript"> const target1 = function () {
return `我是一个target1函数`;
};
const p3 = new Proxy(target1, {
apply: function () {
return `我是一个代理函数`;
},
});
console.log(p3()); //我是一个代理函数
3.3.1例子:
javascript"> 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运算符。
javascript"> 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命令作用的构造函数。
javascript">const p6 = new Proxy(function () { }, {
construct(target, args, newTarget) {
console.log(...args); //2
return { value: 52 }
}
})
console.log(new p6(2).value); //52
注意:由于construct()拦截的是构造函数,所以它的目标对象必须是函数,否则就会报错。
3.6ownKeys()
说明:ownKeys()方法用来拦截对象自身属性的读取操作。
javascript"> const p7 = new Proxy({ name: "张三", age: "18" }, {
ownKeys(target) {
return ["name"]
}
})
console.log(Object.keys(p7)); //name
注意:ownKeys()方法返回的数组之中,必须包含原对象的所有属性,且不能包含多余的属性,否则报错。