首页 > 其他 > 详细

ES6 之 Proxy

时间:2019-08-04 23:18:04      阅读:98      评论:0      收藏:0      [点我收藏+]

概述

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改。

Proxy 可以理解在目标对象架设一个“拦截”层外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和修改

  var obj = new Proxy({}, {
    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}`)
      return Reflect.get(target, key, value, receiver)
    }
  })
  obj.count = 1 // 触发 set 事件 setting count
  ++obj.count //  触发 get 和 set 事件 getting count setting count

Proxy 重载了点运算符,用自己的定义覆盖了语言的原始定义。

ES6 提供了 Proxy 构造函数,用于生成 Proxy 实例。

/**
 * new Proxy() 生成一个 Proxy 实例
 * target 参数表示所要拦截的目标对象
 * handler 参数也是一个对象,用来定制拦截行为
 */
let proxy = new Proxy(target, handler)

注意:

要使 Proxy 起作用,必须针对 Proxy 实例进行操作,而不是目标对象。

如果 handler 没有设置任何拦截,那句等同于直接通向源对象。

例子:

  let target = {}
  let handler = {}
  var proxy = new Proxy(target, handler)
  proxy.count = 1
  console.log(proxy.count) // 1
  target.count = 2
  console.log(target.count) // 2

现在有一个技巧:将 Proxy 设置到 object.proxy 属性中,从而可以在 object 对象上调用。

let object = {
  proxy: new Proxy(target, handler)
}

也可以将 proxy 直接挂载到原型上

let proxy = new  Proxy({}, {
  get: function(target, handler) {
    return ‘houfee‘
  }
})

let obj = Object.create(proxy)

console.log(obj.name) // houfee

// proxy 是 obj 原型上的对象,根据原型链会在 proxy 对象读取该属性,导致被拦截

同一个拦截器函数设置多个操作:

var handler = {
  get: function(target, name) {
    if(name === ‘prototype‘) {
      return Object.prototype
    }
    return `holle ${name}`
  },

  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)

console.log(fproxy(2, 5)) // 2
console.log(new fproxy(2, 5)) // {value: 5}
console.log(fproxy.prototype === Object.prototype) // true
console.log(fproxy.houfee) // holle houfee

 

方法

1.get(target, propKey, receiver)

拦截对象属性的读取,比如 proxy.houfee 和 proxy[‘houfee‘],最后一个参数receiver是一个可选参数。

 

2.set(target, propKey, value, receiver)

拦截对象属性的设置,比如 proxy.houfee = v 和 proxy[‘houfee‘] = v ,返回一个boolean值

 

3.has(target, propKey)

拦截 propKey in proxy 的操作,返回一个布尔值。

 

4.deleteProperty(target, propKey)

拦截 delete proxy[propKey] 的操作,返回一个布尔值。

 

5.ownKeys(target)

拦截 Object.getOwnPropertyNames(proxy)、 Object.getOwnPropertySymbols(proxy)、Object(proty),返回一个数组。

该方法返回目标对象所有自身属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。

 

6.getOwnPropertyDescriptor(target, propKey)

拦截 Object.getOwnPropertyDescriptor(target, propKey),返回属性的描述对象。

 

7.defineProperty(target, propKey, propDesc)

拦截 Object.defineProperty(target, propKey, propDesc)、Object.defineProperties(proxy, propDesc),返回一个布尔值。

 

8.preventExtensions(target)

拦截 Object.preventExtensions(proxy),返回一个布尔值。

 

9.getPrototypeOf(target)

拦截 Object.getPrototypeOf(target),返回一个对象。

 

10.isExtensible(target)

拦截 Object.isExtensible(target),返回一个布尔值。

 

11.setPrototypeOf(target, proto)

拦截 Object.setPrototypeOf(target, proto),返回一个布尔值。如果目标对象是函数,呢么还有2种额外操作可以拦截。

 

12.apply(target, object, args)

拦截 Proxy 实例,并将其作为函数调用,比如 proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。

 

13.construct(target, args)

拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(...args)。

 

Proxy 实例的方法

1. get(target, propKey, receiver)

 

2. set(target, propKey, value, receiver)

 

3. apply(target, object, args)

 

4. has(target, propKey)

 

5. construct(target, args)

 

6. deleteProperty(target, propKey)

 

7. defineProperty(target, propKey, propDesc)

 

8. getOwnPropertyDescriptor(target, propKey)

 

9. getPrototypeOf(target)

 

10. isExtensible(target)

 

11. ownKeys(target)

 

12. preventExtensions(target)

 

13. setPrototypeOf(target, proto)

 

 

ES6 之 Proxy

原文:https://www.cnblogs.com/houfee/p/11300204.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!