es6的Proxy是什么?
可以理解为,是在访问对象前的一层拦截。只要访问的该对象,就要通过这个一层拦截。这一层的拦截,可以进行数据的过滤和更改
比如下面这个
var p = new Proxy({},{ get:function(){ return '没有这个属性' } }) p.name = '张三' p.age // "没有这个属性" p.name //张三
上面的内容说,在读取p里的属性的时候,如果不存在返回 '没有这个属性'
它有很多种截取属性。
- get(target, propKey, receiver):拦截对象属性的读取,比如
proxy.foo
和proxy['foo']
。 - set(target, propKey, value, receiver):拦截对象属性的设置,比如
proxy.foo = v
或proxy['foo'] = v
,返回一个布尔值。 - has(target, propKey):拦截
propKey in proxy
的操作,返回一个布尔值。 - deleteProperty(target, propKey):拦截
delete proxy[propKey]
的操作,返回一个布尔值。 - ownKeys(target):拦截
Object.getOwnPropertyNames(proxy)
、Object.getOwnPropertySymbols(proxy)
、Object.keys(proxy)
、for...in
循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()
的返回结果仅包括目标对象自身的可遍历属性。 - getOwnPropertyDescriptor(target, propKey):拦截
Object.getOwnPropertyDescriptor(proxy, propKey)
,返回属性的描述对象。 - defineProperty(target, propKey, propDesc):拦截
Object.defineProperty(proxy, propKey, propDesc)
、Object.defineProperties(proxy, propDescs)
,返回一个布尔值。 - preventExtensions(target):拦截
Object.preventExtensions(proxy)
,返回一个布尔值。 - getPrototypeOf(target):拦截
Object.getPrototypeOf(proxy)
,返回一个对象。 - isExtensible(target):拦截
Object.isExtensible(proxy)
,返回一个布尔值。 - setPrototypeOf(target, proto):拦截
Object.setPrototypeOf(proxy, proto)
,返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。 - apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如
proxy(...args)
、proxy.call(object, ...args)
、proxy.apply(...)
。 - construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如
new proxy(...args)
。
第一种:
get
get这个方法接收三个参数。第一个为操作对象,第二个是属性名,第三个是proxy实例本身。第三个参数不是必填参数
var tar = { name:"lly" } var pro = new Proxy(tar,{ get:function(target,propkey){ if(propkey in target){ return target[propkey] }else{ throw new RangeError("你错的也太狠了") } } }) pro.name // lly pro.age // RangeError: 你错的也太狠了
上面的内容说道,访问的对象不存在的话,抛出一个错误
第二种
set
这个方法,接收四个参数 访问对象、访问属性、访问的属性值、proxy实例对象
这次例子我们换一个写法,让我们熟悉更多写法 我们来看下面这个例子
var handel = { set:function(obj,prop,value){ if(prop === 'age'){ if(value > 100){ throw new RangeError("你是老妖怪吧") } } } } var p = new Proxy({},handel); p.age = 200 //抛出一个错误 RangeError: 你是老妖怪吧
这个set可以拦截访问对象要添加的值。如果值不符合拦截器的规则,就会抛出错误。
第三种
apply
apply
方法拦截函数的调用、call
和apply
操作。
方法接收三个参数 目标对象、目标对象的上下文对象(this
)和目标对象的参数数组。
我们看下面这个例子
function d(){ return "曾沛慈" } var p = new Proxy(d,{ apply:function(){ return "可乐" } }) p(); //可乐
上面代码中,变量p
是 Proxy 的实例,当它作为函数调用时(p()
),就会被apply
方法拦截,返回一个字符串。
var handel = { has(target,key){ if(key[0] == "_"){ return false } return key in target; } } var obj = {_name:'lly',name:"cyd"} var p = new Proxy(obj,handel); '_name' in p //false