![100行代碼讓您學會JavaScript原生的Proxy設計模式](http://p2.ttnews.xyz/loading.gif)
面向對象設計裡的設計模式之Proxy(代理)模式,相信很多朋友已經很熟悉了。比如我之前寫過代理模式在Java中實現的兩篇文章:
其實和Java一樣,JavaScript從語言層面來講,也提供了對代理這個設計模式的原生支持。我們用一個不到100行代碼的例子來看看吧。
下面的代碼創建了一個名叫Jerry的Employee對象,然後用函數hireEmployee僱用該Employee進行JavaScript開發:
function Employee(name){
this.name = name;
};
Employee.prototype.work = function(language){
console.log(this.name + " is developing with: " + language);
}
let jerry = new Employee("Jerry");
function hireEmployee(employee, language){
employee.work(language);
}
hireEmployee(jerry, "JavaScript");
![100行代碼讓您學會JavaScript原生的Proxy設計模式](http://p2.ttnews.xyz/loading.gif)
打印輸出:
Jerry is developing with: JavaScript
現在Jerry在他的業餘時間裡想學習一些其他的編程語言,但是不想影響自己的本職工作。用技術語言來講,就是希望Employee原型方法work執行時,打印一行額外的信息,但是不允許修改Employee函數和Employee.prototype.work本身。這時Proxy這種代理模式就派上用場了。
我們為work方法創建一個代理邏輯:
var proxyLogic = {
get: function(target, name) {
if( name == "work"){
var oriFun = target[name].bind(target);
return function(language){
oriFun(language);
console.log("and also study other language in spare time");
}
}
}
};
重點看第二行的get方法。兩個輸入參數,target和name。Target代表當前執行方法的實例,即方法調用者。Name代表具體的方法名稱。第4行我們把原始方法取出來,存放到變量oriFun裡。第五行返回一個新的JavaScript函數,該函數體的實現邏輯為首先在第六行調用原始方法,然後在第七行執行額外的邏輯。
大家在回憶我之前介紹Java InvocationHandler實現動態代理的文章:
是不是思路完全一樣?都是在代理邏輯裡調用原始方法,然後再執行額外的代碼。
這個proxyLogic生成後,怎麼把它同我們原始的需要被代理的代碼關聯起來呢?
只需要1行代碼:
var jerryProxy = new Proxy(jerry, proxyLogic );
Proxy函數是JavaScript提供的原生代理構造器,需要兩個輸入參數:
第一個輸入參數是我們的Employee實例,即需要被代碼的對象實例,第二個輸入參數是我們開發好的代理邏輯。返回的即是裝配好的代理對象,該代理對象的work方法實現在第二個輸入參數裡。
現在我們再次調用hireEmployee,傳入Proxy構造器返回的代理對象:
hireEmployee(jerryProxy, "JavaScript");
打印輸出,代理邏輯生效了:
和Java的Invocation一樣優雅地實現了代理設計模式。
使用Proxy代理設計模式的一個實際例子,請參考我的文章:
閱讀更多 汪子熙SAP 的文章
關鍵字: 設計模式 技術 JavaScript