# 代理模式
在我們需要在一個對象后多次進行訪問控制訪問和上下文,代理模式是非常有用處的。
當實例化一個對象開銷很大的時候,它可以幫助我們控制成本,提供更高級的方式去關聯和修改對象,就是在上下文中運行一個特別的方法。
在jQuery核心中,一個jQUery.proxy()方法在接受一個函數的輸入和返回一個一直具有特殊上下文的新的實體時存在。這確保了它在函數中的值時我們所期待的的值。
一個使用該模式的例子,在點擊事件操作時我們利用了定時器。設想我用下面的操作優先于任何添加的定時器:
~~~
$( "button" ).on( "click", function () {
// 在這個函數中,'this'代表了被當前被點擊的那個元素對象
$( this ).addClass( "active" );
});
~~~
如果想要在addClass操作之前添加一個延遲,我們可以使用setTiemeout()做到。然而不幸的是這么操作時會有一個小問題:無論這個函數執行了什么在setTimeout()中都會有個一個不同的值在那個函數中。而這個值將會關聯window對象替代我們所期望的被觸發的對象。
~~~
$( "button" ).on( "click", function () {
setTimeout(function () {
// "this" 無法關聯到我們點擊的元素
// 而是關聯了window對象
$( this ).addClass( "active" );
});
});
~~~
為解決這類問題,我們使用jQuery.proxy()方法來實現一種代理模式。通過調用它在這個函數中,使用這個函數和我們想要分配給它的this,我們將會得到一個包含了我們所期望的上下文中的值。如下所示:
~~~
$( "button" ).on( "click", function () {
setTimeout( $.proxy( function () {
// "this" 現在關聯了我們想要的元素
$( this ).addClass( "active" );
}, this), 500);
// 最后的參數'this'代表了我們的dom元素并且傳遞給了$.proxy()方法
});
~~~
jQuery代理方法的實現如下:
~~~
// Bind a function to a context, optionally partially applying any
// arguments.
proxy: function( fn, context ) {
if ( typeof context === "string" ) {
var tmp = fn[ context ];
context = fn;
fn = tmp;
}
// Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
if ( !jQuery.isFunction( fn ) ) {
return undefined;
}
// Simulated bind
var args = slice.call( arguments, 2 ),
proxy = function() {
return fn.apply( context, args.concat( slice.call( arguments ) ) );
};
// Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
return proxy;
}
~~~
- 前言
- 簡介
- 什么是設計模式?
- 設計模式的結構
- 編寫設計模式
- 反模式
- 設計模式的分類
- 設計模式分類概覽表
- JavaScript 設計模式
- 構造器模式
- 模塊化模式
- 暴露模塊模式
- 單例模式
- 觀察者模式
- 中介者模式
- 原型模式
- 命令模式
- 外觀模式
- 工廠模式
- Mixin 模式
- 裝飾模式
- 亨元(Flyweight)模式
- JavaScript MV* 模式
- MVC 模式
- MVP 模式
- MVVM 模式
- 最新的模塊化 JavaScript 設計模式
- AMD
- CommonJS
- ES Harmony
- JQuery 中的設計模式
- 組合模式
- 適配器模式
- 外觀模式
- 觀察者模式
- 迭代器模式
- 惰性初始模式
- 代理模式
- 建造者模式
- jQuery 插件的設計模式
- JavaScript 命名空間模式
- 總結
- 參考