get(target, propKey,receiver)
作用:拦截某个属性的读取操作,可以接受三个参数,依次为目标对象、属性名和 proxy 实例本身
{
//这里target为{}
const proxy = new Proxy({}, {
//拦截对象的读取
get: function(target, property, receiver) {
return receiver;
}
});
console.log(proxy.a); //Proxy {}
console.log(proxy); //Proxy {}
console.log(proxy.a===proxy);//true
const d = Object.create(proxy);//被继承
console.log(d.a === d) // true
}
set(target, propKey, value,receiver)
作用:用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选。返回一个布尔值。
{
"use strict"//严格模式
let obj={};
//如果目标对象自身的某个属性,不可写且不可配置(即configurable和writable都为false),那么set方法将不起作用
Object.defineProperty(obj,"name",{
configurable:true, //允许删除
writable:true, //允许修改
value:"james" //name属性的值
});
let proxy=new Proxy(obj,{
//拦截Proxy代理对象属性是否能被设置
set(target, key,value,proxy){
return Reflect.set(target,key,value,proxy);
}
})
console.log(obj.name);//james
proxy.name = 'haha';
console.log(proxy.name); //haha
}
//set代理如果没有返回true,就会报错。比如没有return语句或者return false;return;都会报错
{
"use strict" //严格模式
let obj={name:"james"};
let proxy=new Proxy(obj,{
set(target, propKey, value,receiver){
return target[propKey]="tang1"; //不加return语句会报错 设置为固定返回值
// return Reflect.set(target,propKey,value,receiver); //test 设置对应的值
}
})
proxy.test="test";
console.log(proxy.test); // test
console.log(proxy); //Proxy {name: "james", test: "tang1"}
}
has(target, propKey)
作用:用来拦截HasProperty操作,用来判断对象是否具有某个属性。典型的操作就是in运算符。has方法可以接受两个参数,分别是目标对象、需查询的属性名。返回一个布尔值。就算你自定义返回的不是布尔值,也会转换布尔值。
// 1、如果某个属性的configurable被设置为false或者整个对象被设置为禁止扩展的话。使用in运算符时,被has方法拦截时,必须返回target[key]所对应的值,否则会报错
// 2、has拦截的不是hasProperty()方法,也不会拦截has...in操作。
{
let obj={
a:1,
b:2
}
Object.defineProperty(obj,"c",{
configurable:true,
writable:true,
value:"123",
enumerable:false,//此属性是否可以被枚举(使用for...in或Object.keys())。设置为true可以被枚举;设置为false,不能被枚举。默认为false
})
//Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性
Object.preventExtensions(obj);
//Object.isExtensible()方法 判断一个对象是否可扩展,即是否可以给它添加新属性
console.log('Object.isExtensible',Object.isExtensible(obj)); //false
let proxy=new Proxy(obj,{
has(target,key){
if(key==="a"){
return target[key];//被has方法拦截时,必须返回target[key]所对应的值,否则会报错
}
if(key==="b"){
return target[key]; //被has方法拦截时,必须返回target[key]所对应的值,否则会报错
}else{
return target[key]; //被has方法拦截时,必须返回target[key]所对应的值,否则会报错
}
},
set(target,key,value,receiver){
return Reflect.set(target,key,value,receiver); //设置对应的值
}
})
console.log("c" in proxy); //true
console.log("a" in proxy); //true
console.log("d" in proxy); //false
proxy.e = "E"; //设置失败 因为前面的Object.preventExtensions(obj)让一个对象变的不可扩展,也就是永远不能再添加新的属性
console.log(proxy); //Proxy {a: 1, b: 2, c: "123"}
//proxy.d = '4'; //报错 因为前面设置了 Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性!!
for(let key in proxy){
console.log(key); //a b (c因为 enumerable 属性被设置为false,故读取不到)
}
//无法使用forEach()
// proxy.forEach(item=>{
// console.log(item); //报错 proxy.forEach is not a function
// })
//无法使用for of
// for(let key of proxy){
// console.log(key); //报错 proxy is not iterable
// }
}