# Proxy
- 只能是针对Proxy实例,如直接访问原对象不会有变化
用于修改某些操作的默认行为,等同于在语言层作出修改,属于 “元编程”,meta programming by 阮一峰 es6-proxy
理解:每当去12306去买票,都找一下黄牛哥,至于他干了啥,我们心里是没点数的。形成一个“代理”的机制。
在JS语言世界中,如果我们想去访问一个对象A(Object类型、可能是一个Function),对象A前面搭建了一座桥,这座桥可以过滤访客和改写返回的结果
const obj=new Proxy({},{
get:function(target,propKey,receiver){
console.log(`getting ${propKey}!`)
return Reflect.get(target,propKey,receiver)
},
set:function(target,propKey,value,receiver){
console.log(`setting ${propKey}!`)
return Reflect.set(target,propKey,value,receiver)
}
})
// obj.name="hello world"
// obj.name
# es6 Proxy 定义声明
- this 执行proxy
var proxy = new Proxy(target,handler)
target 参数表示要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为
# 把proxy 实例作为其他对象的原型
- 对象上的原型所有属性都会被改写,比如construstor、proto、
- 一般都会不去改写 propKey: prototype、proto、constructor、apply、bind、call
const proxy= new Proxy({},{
get:function(target,propKey){
return 'yeeh,I proxy this!'
}
})
const obj= Object.create(proxy)
# 同一个拦截函数,可以拦截多个操作
var handler= {
// 代理
get :function(target,prop){
if(prop==='prototype'){
return Object.prototype
}
return 'Hello, '+prop
},
// 普通函数
apply:function(target,thisBinding,args){
return args[0]
},
// 构造器
construct:function(target,args){
return {value:args[1]}
}
}
var fproxy=new Proxy(function(x,y){
return x+y
},handler)
fproxy(1,2) //1
new fproxy(1,2) // {value:1}
fproxy.prototype===Object.prototype // true
fproxy.foo //
# 拦截属性
- get(target,propKey,receiver):拦截对象属性的读取,比如proxy.foo
- set(target,propKey,value,receiver):拦截对象属性的设置,比如 proxy.foo='hello',返回一个布尔值
- has(target,propKey):拦截propKey in proxy 的操作,返回一个布尔值
var obj=new Proxy({},{
get:function(target,propKey,receiver){
console.log(`getting ${propKey}!`)
return Reflect.get(target,propKey,receiver)
},
set:function(target,propKey,value,receiver){
console.log(`setting ${propKey}!`)
return Reflect.set(target,propKey,value,receiver)
},
has:function(target,propKey){
return true
}
})
'22' in obj //true
- deleteProperty(target,propKey):拦截delete proxy[propKey] 的操作,返回一个布尔值
- ownKeys(target),拦截以下:
Object.getOwnPropertyNames(proxy)
Object.getOwnPropertySymbols(proxy)
Object.keys(proxy)
仅包括对象自身可遍历属性for ... in
- 返回一个数组,
- **getOwnPropertyDescriptor(target,propKey)**拦截
Object.getOwnPropertyDescriptor(proxy,proxyKey)
,返回属性的描述对象 - defineProperty(target,propKey,propDesc),拦截
Object.defineProperty(proxy,propKey,propDesc)
、Object.definePropertries(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,objet,args) 拦截Proxy 实例作为函数调用的操作,比如
proxy(...args)
、proxy.call(object,...args)
、proxy.apply(...)
- constuct(target,args) 拦截Proxy 实例作为构造函数调用的操作,比如
new proxy(...args)
# web服务的拦截Proxy
适合写web服务客户端,也可以实现数据库的ORM 层
function createWebServer(baseUrl){
return new Proxy({},{
get(target,propKey,receive){
return ()=> httpGet(baseUrl+'/'+propKey)
}
})
}
const service = createWebServer('http://baidu.com')
service.employees().then(res=>{
console.log(res)
})