1,Proxy用于修改某些操作的默认行为和访问器属性的行为类似,在对象的前面多一层代理,
const obj = { //对象字面量 name : 'obama', age : 73 }obj.name //obama//ES5中定义属性的特性方法,访问器属性Object.defineProperty(); Object.defineProperty(obj,name',{ get :function(){ return 'hello presdent'; } }); obj;//{age : 73}此时name属性被定义为访问器属性 obj.name // 'hello presdent'; var newObj = { _name : 'obama', get name(){ //不一样的写法 return 'hello presdent'; } } //ES6中是用Proxy代理的写法 var proxy = new Proxy(targetn,handler(target,property)) //第一个参数是对象,第二个是要操作的方法对象,也有两个属性,一个是目标对象,一个是属性 var obj = { name : 'obama', age : 73 }; var fn = { get : function(obj){ alert('hello presdent') } }
Proxy支持的拦截操作
1,get(),用于读取某个属性的操作var person = { name : 'obama'};var proxy = new Proxy(person,{ get : function(target,property){ if(property in target){ return target[property] }else{ throw new ReferenceError('you input wrong property') } }})proxy.name //obama;proxy.age //Uncaught ReferenceError: you input wrong propertyperson.age //undefind//此属性可以继承var pro = Object.create(proxy);pro.name //obama;
2,set(),用于拦截属性的赋值操作
var obj = { set : function(obj,prop,value){ if(prop ==='age'){ if(Number.isInteger(value)){ obj[prop] = value; }else{ throw new Error('not a number') } } else{ obj[prop] = value; } }};var person = new Proxy({},obj);person.age = 12;//12;person.age = 'test' //Uncaught Error: not a number//可以使用这个方法不允许访问内部带有下划线的变量function validat(key,action){ if(key[0] === '_'){ throw new Error('不允许访问内部变量') }}var obj = { get(target,key){ validat(key,'get'); return target[key] }, set(target,key,value){ validat(key,'set'); return target[key] = value; }};var target = {};var proxy = new Proxy(target,obj);
3,apply()拦截调用和apply和call操作
4,has()隐藏某些属性,不被in操作符发现var handle = { has(target,key){ if(key[0] === "_"){ return false; } return key in target }};var obj = { name : 'obama'}var proxy = new Proxy(obj,handle);
5,construct()拦截new命令
var Fn = function(){return 'the world'};var handle = { construct : function(){ throw new Error('不能使用NEW操作符') }};var proxy = new Proxy(Fn,handle);var newp = new proxy;//Uncaught Error: 不能使用NEW操作符var newp = proxy() //the world//同样如果返回的不是对象也会报错
6,deleteProperty()拦截删除操作,如果返回的不是true就无法删除
var handle = { deleteProperty(target,key){ return false; //返回错误或者false都不能删除 }};var obj ={ name : 'obama'};var presdent = new Proxy(obj,handle);delete presdent.name //false;
7,enumerate()拦截for in 循环
8,getOwnPropertyDescriptor(),
9,getPrototypeOf()10,isExtensible(),11,Own.keys()拦截Object.keys()方法12,preventExtensions();13,setProtypeOf();14,Proxy.revocable()返回一个可以取消的Proxy实例var handle = {};var obj = {};var s= Proxy.revocable(obj,handle);//返回一个对象,s //{proxy: Proxy, revoke: ƒ}s.proxy.name = 'obama'; //obamas.revoke();s.proxy.name //Uncaught TypeError: Cannot perform 'get' on a proxy
Reflect对象,包含一些特殊的属性,默认是对象的原始行为,Proxy改写的就是这些行为