文章目录
Proxy
1.0 概述
Proxy 用于修改某些操作的默认行为, 等同于在语言层面做出修改, 所以书序一种 “元编程”, 即对编程语言进行编程.
Proxy 可以理解成, 在目标对象之前假设一层 “拦截” , 外界对该对象的访问, 都必须先通过这层拦截, 因此提供了一种机制, 可以对外界的访问进行过滤和改写. 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); } });
上面代码对一个空对象架设了一层拦截, 重定义了属性的读取
get 和设置
set` 的行为.obj.count = 1 // setting count! 赋值操作走 set 方法. obj.count // getting count! 取值操作 走 get 方法
上面代码说明,Proxy 实际上重载(overload)了点运算符,即用自己的定义覆盖了语言的原始定义。
ES6 原生提供 Proxy 构造函数, 用来生成 Proxy 实例
let proxy = new Proxy(targetObj, handler)
Proxy 对象的所有用法,都是上面这种形式,不同的只是
handler
参数的写法。其中,new Proxy()
表示生成一个Proxy
实例,target
参数表示所要拦截的目标对象,**handler
参数也是一个对象,**用来定制拦截行为。
下面是另一个拦截读取属性行为的例子。
var proxy = new Proxy({ }, { get: function(target, propKey) { return 35; } }); proxy.time // 35 proxy.name // 35 proxy.title // 35
注意,要使得
Proxy
起作用,必须针对Proxy
实例(上例是proxy
对象)进行操作,而不是针对目标对象(上例是空对象)进行操作。
2.0 Proxy 实例的方法
2.1 get()
get
方法用于拦截某个属性的读取操作, 可以接收 三个 参数, 依次为 目标对象, 属性名, 和 proxy 实例本身(严格的说, 是操作行为所针对的对象), 其中最后一个参数可选.let person = { name: 'Gene', age: 18, } let proxy = new Proxy(person, { get(target, propKey, receiver) { console.log(target, propKey, receiver); // {name: "Gene", age: 18}, "name", Proxy:{name:'Gene',age:18} if (propKey in target) { return target[propKey] } else { throw new ReferenceError('抱歉引用错误') } } }) console.log(proxy.name); // Gene proxy.sex // ReferenceError: 抱歉引用错误
上面代码表示, 如果访问的目标对象不存在的属性, 会抛出一个错误, 如果没有这个拦截函数, 访问不存在的属性, 只会返回
undefined
get
方法可以被继承let proxy = new Proxy({ }, { get(target, p, receiver) { console.log('当前为GET方法,参数为 -->' + p) // 当前为GET方法,参数为 -->foo return target[p] } }) let obj = Object.create(proxy) obj