proxy 的概念
Proxy 能够了解成,在指标对象之前架设一层“拦挡”,外界对该对象的拜访,都必须先通过这层拦挡,因而提供了一种机制,能够对外界的拜访进行过滤和改写。Proxy 这个词的原意是代理,用在这里示意由它来“代理”某些操作,能够译为“代理器”。
var proxy = new Proxy(target, handler);
new Proxy()
示意生成一个Proxy
实例,target
参数示意所要拦挡的指标对象,handler
参数也是一个对象,用来定制拦挡行为
Proxy 实例也能够作为其余对象的原型对象。
var proxy = new Proxy({}, {get: function(target, propKey) {return 35;}
});
let obj = Object.create(proxy);
obj.time // 35
下面代码中,
proxy
对象是obj
对象的原型,obj
对象自身并没有time
属性,所以依据原型链,会在proxy
对象上读取该属性,导致被拦挡。
同一个拦截器函数,能够设置拦挡多个操作。
13 种 Proxy 反对的拦挡操作:
- 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)
。
Proxy 实例的办法
get()
get
办法用于拦挡某个属性的读取操作,能够承受三个参数,顺次为指标对象、属性名和 proxy 实例自身(严格地说,是操作行为所针对的对象),其中最初一个参数可选。
set()
set
办法用来拦挡某个属性的赋值操作,能够承受四个参数,顺次为指标对象、属性名、属性值和 Proxy 实例自身,其中最初一个参数可选。
假设 Person
对象有一个 age
属性,该属性应该是一个不大于 200 的整数,那么能够应用 Proxy
保障 age
的属性值符合要求。
apply()
apply
办法拦挡函数的调用、call
和 apply
操作。
apply
办法能够承受三个参数,别离是指标对象、指标对象的上下文对象(this
)和指标对象的参数数组。
has()
has()
办法用来拦挡 HasProperty
操作,即判断对象是否具备某个属性时,这个办法会失效。典型的操作就是 in
运算符。
has()
办法能够承受两个参数,别离是指标对象、需查问的属性名。
construct()
construct()
办法用于拦挡 new
命令
deleteProperty()
deleteProperty
办法用于拦挡 delete
操作,如果这个办法抛出谬误或者返回 false
,以后属性就无奈被delete
命令删除。
defineProperty()
defineProperty()
办法拦挡了 Object.defineProperty()
操作
getOwnPropertyDescriptor()
getOwnPropertyDescriptor()
办法拦挡Object.getOwnPropertyDescriptor()
,返回一个属性形容对象或者undefined
。
getPrototypeOf()
getPrototypeOf()
办法次要用来拦挡获取对象原型。具体来说,拦挡上面这些操作。
Object.prototype.__proto__
Object.prototype.isPrototypeOf()
Object.getPrototypeOf()
Reflect.getPrototypeOf()
-
instanceof
Proxy.revocable()
Proxy.revocable()
办法返回一个可勾销的 Proxy 实例
this 的问题
尽管 Proxy 能够代理针对指标对象的拜访,但它不是指标对象的通明代理,即不做任何拦挡的状况下,也无奈保障与指标对象的行为统一。次要起因就是在 Proxy 代理的状况下,指标对象外部的
this
关键字会指向 Proxy 代理。
Proxy 也能够用来实现数据库的 ORM 层