Proxy
对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。其实就是在对目标对象的操作之前提供了拦截,可以对外界的操作进行过滤和改写,修改某些操作的默认行为,这样我们可以不直接操作对象本身,而是通过操作对象的代理对象来间接来操作对象
今天学习了两个proxy的新用法
1.校验类型
const validator = {
name:(value)=>{
let reg = /^[\u4E00-\u9FAS]/
if(typeof value == 'string' && reg.test(value)){
return true
}
return false
},
age:(value)=>{
if(typeof value == 'number' && value >= 18){
return true
}
return false
}
}
function Person (name,age){
this.name = name
this.age = age
return new Proxy(this,{
get:(target,key)=>{
return target[key]
},
set:(target,key,value)=>{
// 符合要求再设定
if(validator[key](value)){
return Reflect.set(target[key],value)
}else{
// 不符合抛出错误
throw new Error(key + 'is not right')
}
}
})
}
const a = new Person('小明', 19)
console.log(a)
a.age = 3 // 在此会报错
真正的私有变量
const protectHandler = { //此为定义Proxy的第二个参数,劫持原对象的get和set方法
get (target, key) { //target为目标对象, key为成员变量
isProtected(key, 'get'); //调用isProtected判断是否合法
return target[key]; //如果合法会运行此步,返回目标对象中的成员变量
},
set (target, key, value) { //value为要给成员变量设置的值
isProtected(key, 'set');
target[key] = value; //如果合法会运行此步,设置变量值为value
return true; //成功返回true
};
function isProtected (key, action) { //判断是否合法的函数
if (key[0] === '_') { //规定:如果成员变量名以"_"开头,就视为私有的,抛出异常阻止操作
throw new Error(`Invalid attempt to ${action} private "${key}" property`);
}
}
const yourObj = new Student(); //实例化一个对象
const myObj = new Proxy(yourObj, protectHandler);//给yourObj对象添加protectHandler劫持,
//在set和get时遇到以"_"开头的私有变量名就报错
Proxy(target, handler)
target指的是你实例化的一个类,handler是你定义的劫持规则
const myObj = new Proxy(target, handler)
此时对myObj的get,set操作相当于先通过handler,再作用到target上
在此例中,相当于先判断你要操作的变量是不是内部变量,如果是就禁止操作。