# 代理模式
在我们需要在一个对象后多次进行访问控制访问和上下文,代理模式是非常有用处的。
当实例化一个对象开销很大的时候,它可以帮助我们控制成本,提供更高级的方式去关联和修改对象,就是在上下文中运行一个特别的方法。
在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 命名空间模式
- 总结
- 参考