intro
ES6新特性中新增代理类Proxy
,其构造方法为Proxy(target, handler)
,其中:
- target
被代理的对象|目标
- handler
处理器|中间层代理(用于自定义代理对象的各种可代理操作)。
target
和handler
都是对象。
handler
中的成员方法是固定的(用途也是固定)。
API
handlder
对象中共有13种可代理操作,如下:
(如果没有定义某种操作,那么这种操作会被转发到目标对象上)
getPrototypeOf(target)
当读取被代理对象target
的原型prototype
时会触发该操作。
setPrototypeOf(target, prototype)
给target
设置prototype
时触发。
isExtensible(target)
判断target
是否可扩展时触发。
preventExtensions(target)
设置target
不可扩展时触发。
getOwnPropertyDescriptor(target, prop)
获取target[prop]
的属性描述时触发。
defineProperty(target, property, descriptor)
定义target
的某个属性prop
的属性描述descriptor
时触发。
has(target, prop)
当判断target
是否拥有属性prop
时,触发。
get(target, property, receiver)
读取target
的属性property
时触发。
set(target, property, value, receiver)
设置target
的属性property
为值value
时触发。
get
中的receiver
为Proxy
或继承Proxy的对象
。
set
中的receiver
是最初被调用的对象(通常是Proxy本身)。
deleteProperty(target, property)
删除target
的属性property
时触发。
ownKeys(target)
获取targeet
的所有属性key s
时触发。
apply(target, thisArg, argumentsList)
当目标target
为函数,且被调用时触发。
construct(target, argumentsList, newTarget)
给target
为构造函数的代理对象构造实例时触发。
detail
-
handler.getPrototypeOf(target)
返回一个对象或null(不能返回其他类型的原始值)- JS中,以下5种操作会触发JS引擎读取一个对象的原型(
getPrototypeOf(target)
代理方法的运行)。Object.getPrototypeOf(object)
返回对象object的原型prototype。Reflect.getPrototypeOf(target)
__proto__
对象的该属性是一个访问器属性(一个getter
函数和一个setter
函数)。obj1.isPrototypeOf(obj2)
测试对象obj1是否在对象obj2的原型链上。object instanceof constructor
检测构造函数constructor的prototype属性是否出现在对象object的原型链中的任何位置。
- JS中,以下5种操作会触发JS引擎读取一个对象的原型(
-
handler.setPrototype(target, prototype)
返回Boolean值,表示是否修改了原型。- 本方法可以拦截的操作有:
Object.setPrototypeOf(object, prototype)
Reflect.setPrototypeOf(target, prototype)
- 本方法可以拦截的操作有:
-
handler.isExtensible(target)
返回一个Boolean值(或一个可转换为Boolean值的值)- 会拦截以下操作:
Object.isExtensible(object)
Reflect.isExtensible(target)
- 会拦截以下操作:
-
handler.preventExtensions(target)
返回一个Boolean值- 拦截的操作:
Object.preventExtensions(object)
Reflect.preventExtensions(target)
- 拦截的操作:
-
handler.getOwnPropertyDescriptor(target, prop)
返回一个object
或undefined
- 拦截的操作:
Object.getOwnPropertyDescriptor(object, prop)
Reflect.getOwnPropertyDescriptor(target, prop)
- 拦截的操作:
-
handler.defineProperty(target, property, descriptor
返回一个Boolean值,表示操作成功/失败- 拦截的操作:
Object.defineProperty(object, property, descriptor)
Reflect.defineProperty(target, property, descriptor)
- 拦截的操作:
-
handler.has(target, prop)
返回一个Boolean值handler.has(target, prop)
可以看做是in
操作的trap
。()- 属性查询:
foo in proxy
- 继承属性查询:
foo in Object.create(proxy)
with检查
:with(ptoxy) {(foo);}
Reflect.has(target, prop)
- 属性查询:
-
handler.get(target, property, receiver)
get可以返回任何类型的值- 拦截的操作:
- 读属性:
proxy[foo]
或proxy.foo
- 访问原型链上的属性:
Object.create(proxy)[foo]
Reflect.get(target, property, ?receiver)
- 读属性:
- 拦截的操作:
-
handler.set(target, property, value, receiver
返回Boolean值,表示写操作是否成功。- 拦截的操作:
- 写属性:
proxy[foo] = xxx
或proxy.foo = xxx
- 指定继承者的属性:
Object.create(proxy)[foo] = xxx
Reflect.set(target, property, value, ?receiver)
- 写属性:
- 拦截的操作:
-
handler.deleteProperty(target, property
返回Boolean值,表示删除是否成功。- 拦截的操作:
- 删除属性:
delete proxy[foo]
或delete proxy.foo
Reflect.deleteProperty(target, property)
- 删除属性:
- 拦截的操作:
-
handler.ownKeys(target)
返回一个可枚举对象- 拦截的操作:
Object.getOwnPropertyNames(object)
返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。Object.getOenPropertySymbols(object)
返回一个给定对象自身的所有 Symbol 属性的数组。Object.keys(object)
返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。Reflect.ownKeys(target)
返回一个由目标对象自身的属性键组成的数组。
- 拦截的操作:
-
handler.apply(target, thisArg, argumentsList)
可以返回任何类型的值。- 拦截的操作:
proxy(...args)
Function.prototype.apply()
和Function.prototype.call()
。(即foo.apply()
和foo.call()
)Reflect.apply(target, thisArg, argumentsList)
- 拦截的操作:
-
handler.construct(target, argumentsList, newTarge
) 返回一个对象- 拦截的操作:
new proxy(...args
Reflect.construct(target, argumentsList, newTarget)
- 拦截的操作: