码迷,mamicode.com
首页 > 其他好文 > 详细

ES6中的代理模式-----Proxy

时间:2020-04-04 14:58:55      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:def   兼容性   ref   glob   div   str   handle   color   描述   

技术图片

 

 

 

什么是代理模式

代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式。

所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大对象、文件或其它昂贵或无法复制的资源。

著名的代理模式例子为引用计数(英语:reference counting)指针对象。

当一个复杂对象的多份副本须存在时,代理模式可以结合享元模式以减少内存用量。典型作法是创建一个复杂对象及多个代理者,每个代理者会引用到原本的复杂对象。而作用在代理者的运算会转送到原本对象。一旦所有的代理者都不存在时,复杂对象会被移除。

上面是维基百科中对代理模式的一个整体的定义.而在JavaScript中代理模式的具体表现形式就是ES6中的新增对象---Proxy

 

什么是Proxy对象

 


在MDN上对于Proxy的解释是:

Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。

  简单来说:Proxy对象就是可以让你去对JavaScript中的一切合法对象的基本操作进行自定义.然后用你自定义的操作去覆盖其对象的基本操作.也就是当一个对象去执行一个基本操作时,其执行的过程和结果是你自定义的,而不是对象的.

 

??好吧,用文字表达可能太复杂了.我们还是直接上代码吧.

 

首先Proxy的语法是:

1 let p = new Proxy(target, handler);

其中:

  • target是你要代理的对象.它可以是JavaScript中的任何合法对象.如: (数组, 对象, 函数等等)

  • handler是你要自定义操作方法的一个集合.

  • p是一个被代理后的新对象,它拥有target的一切属性和方法.只不过其行为和结果是在handler中自定义的.

然后让我们来看这段代码:

 1 let obj = {
 2   a: 1,
 3   b: 2,
 4 }
 5 
 6 const p = new Proxy(obj, {
 7   get(target, key, value) {
 8     if (key === ‘c‘) {
 9       return ‘我是自定义的一个结果‘;
10     } else {
11       return target[key];
12     }
13   },
14 
15   set(target, key, value) {
16     if (value === 4) {
17       target[key] = ‘我是自定义的一个结果‘;
18     } else {
19       target[key] = value;
20     }
21   }
22 })
23 
24 console.log(obj.a) // 1
25 console.log(obj.c) // undefined
26 console.log(p.a) // 1
27 console.log(p.c) // 我是自定义的一个结果
28 
29 obj.name = ‘李白‘;
30 console.log(obj.name); // 李白
31 obj.age = 4;
32 console.log(obj.age); // 4
33 
34 p.name = ‘李白‘;
35 console.log(p.name); // 李白
36 p.age = 4;
37 console.log(p.age); // 我是自定义的一个结果

从上面这段代码中,我可以很清楚的看到Proxy对象的作用.即是之前所受的用于定义基本操作的自定义行为.同样的getset操作.没有没代理的对象所得的结果是其JavaScript本身的执行机制运行计算后所得到的.而被代理了的对象的结果则是我们自定义的.

 

Proxy所能代理的范围--handler

 

在上面代码中,我们看到了构造一个代理对象时所传的第二个参数handler,这个handler对象是由getset两个函数方法组成的.这两个方法会在一个对象被getset时被调用执行,以代替原生对象上的操作.那么为什么在handler,定义getset这两个函数名之后就代理对象上的getset操作了呢?

 

实际上handler本身就是ES6所新设计的一个对象.它的作用就是用来自定义代理对象的各种可代理操作。它本身一共有13中方法,每种方法都可以代理一种操作.其13种方法如下:

 1 handler.getPrototypeOf()
 2 
 3 // 在读取代理对象的原型时触发该操作,比如在执行 Object.getPrototypeOf(proxy) 时。
 4 
 5 handler.setPrototypeOf()
 6 
 7 // 在设置代理对象的原型时触发该操作,比如在执行 Object.setPrototypeOf(proxy, null) 时。
 8 
 9 handler.isExtensible()
10 
11 // 在判断一个代理对象是否是可扩展时触发该操作,比如在执行 Object.isExtensible(proxy) 时。
12 
13 handler.preventExtensions()
14 
15 // 在让一个代理对象不可扩展时触发该操作,比如在执行 Object.preventExtensions(proxy) 时。
16 
17 handler.getOwnPropertyDescriptor()
18 
19 // 在获取代理对象某个属性的属性描述时触发该操作,比如在执行 Object.getOwnPropertyDescriptor(proxy, "foo") 时。
20 
21 handler.defineProperty()
22 
23 // 在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 Object.defineProperty(proxy, "foo", {}) 时。
24 
25 handler.has()
26 
27 // 在判断代理对象是否拥有某个属性时触发该操作,比如在执行 "foo" in proxy 时。
28 
29 handler.get()
30 
31 // 在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。
32 
33 handler.set()
34 
35 // 在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1 时。
36 
37 handler.deleteProperty()
38 
39 // 在删除代理对象的某个属性时触发该操作,比如在执行 delete proxy.foo 时。
40 
41 handler.ownKeys()
42 
43 // 在获取代理对象的所有属性键时触发该操作,比如在执行 Object.getOwnPropertyNames(proxy) 时。
44 
45 handler.apply()
46 
47 // 在调用一个目标对象为函数的代理对象时触发该操作,比如在执行 proxy() 时。
48 
49 handler.construct()
50 
51 // 在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行new proxy() 时。

Proxy的作用

 

对于代理模式Proxy的作用主要体现在三个方面:

1、 拦截和监视外部对对象的访问

2、 降低函数或类的复杂度

2、 在复杂操作前对操作进行校验或对所需资源进行管理

而对于这三个使用方面的具体表现大家可以参考这篇文章--实例解析ES6 Proxy使用场景

Proxy的兼容性

 技术图片

 

 

参考资料:

最后附上原文链接

ES6中的代理模式-----Proxy

标签:def   兼容性   ref   glob   div   str   handle   color   描述   

原文地址:https://www.cnblogs.com/Object-L/p/12631453.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!