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

 

 

 

什麼是代理模式

代理模式(英語:Proxy Pattern)是程序設計中的一種設計模式。javascript

所謂的代理者是指一個類別能夠做爲其它東西的接口。代理者能夠做任何東西的接口:網絡鏈接、內存中的大對象、文件或其它昂貴或沒法複製的資源。html

著名的代理模式例子爲引用計數(英語:reference counting)指針對象。java

當一個複雜對象的多份副本須存在時,代理模式能夠結合享元模式以減小內存用量。典型做法是建立一個複雜對象及多個代理者,每一個代理者會引用到本來的複雜對象。而做用在代理者的運算會轉送到本來對象。一旦全部的代理者都不存在時,複雜對象會被移除。es6

上面是維基百科中對代理模式的一個總體的定義.而在JavaScript中代理模式的具體表現形式就是ES6中的新增對象---Proxy設計模式

 

什麼是Proxy對象

 


在MDN上對於Proxy的解釋是:數組

Proxy 對象用於定義基本操做的自定義行爲(如屬性查找,賦值,枚舉,函數調用等)。網絡

  簡單來講:Proxy對象就是可讓你去對JavaScript中的一切合法對象的基本操做進行自定義.而後用你自定義的操做去覆蓋其對象的基本操做.也就是當一個對象去執行一個基本操做時,其執行的過程和結果是你自定義的,而不是對象的.app

 

😓好吧,用文字表達可能太複雜了.咱們仍是直接上代碼吧.函數

 

首先Proxy的語法是:post

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的做用主要體如今三個方面:

一、 攔截和監視外部對對象的訪問

二、 下降函數或類的複雜度

二、 在複雜操做前對操做進行校驗或對所需資源進行管理

而對於這三個使用方面的具體表現你們能夠參考這篇文章--實例解析ES6 Proxy使用場景

Proxy的兼容性

 

 

 

參考資料:

最後附上 原文連接
相關文章
相關標籤/搜索