es6 proxy

proxy 比 Object.defineProperty好在哪?可以监听 属性的添加和删除、数组索引和长度的变更,并可以支持 Map、Set、WeakMap 和 WeakSet!
简单粗暴的语法: new Proxy = (target, handler)。

下面是个小栗子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function getProxyInstance (obj){
let handler = {
get:function(target, key, receiver){
console.log(`getting ${key}`)
return Reflect.get(target, key, receiver)
},
set:function(target, key,value, receiver){
console.log(`setting ${key} to : ${value}`)
return Reflect.set(target, key,value, receiver)
}
}
return new Proxy(obj, handler)
}

var arr = [1,2,3]
var p =getProxyInstance(arr)

p[2] // getting 2 ,3
p[2]=300 // setting 2 to : 300
p[3] // getting 3, undefined
p[3]=400 // setting 3 to : 4, 400
p.fruit // getting fruit, undefined
p.fruit = 'apple' // setting fruit to : apple, 'apple'
arr //  [1, 2, 300, 4, fruit: "apple"]

详细的handler支持13种操作。
下面是 Proxy 支持的拦截操作一览,一共 13 种。

  1. get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy[‘foo’]。
  2. set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。
  3. has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
  4. deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
  5. ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、
    Object.getOwnPropertySymbols(proxy)、
    Object.keys(proxy)、
    for…in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
  6. getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
  7. defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
  8. preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
  9. getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
  10. isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
  11. setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  12. apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
  13. construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(…args)。