jQuery中$.proxy()的原理和使用
jQuery.proxy(),接受一个函数,然后返回一个新函数,并且这个新函数始终保持了特定的上下文(context )语境。
jQuery.proxy( function, context )
function:将要改变上下文语境的函数。
context:函数的上下文语境(`this`)会被设置成这个 object 对象。
jQuery.proxy( context, name )
context:函数的上下文语境会被设置成这个 object 对象。
name:将要改变上下文语境的函数名(这个函数必须是前一个参数 ‘context’ 对象的属性)
这个方法通常在向一个元素上附加事件处理函数时,上下文语境实际是指向另一个对象的情况下使用。
另外,jQuery 能够确保即使你绑定的函数是经过 jQuery.proxy() 处理过的函数,你依然可以用原先的函数来正确地取消绑定。
看一下官方的例子:
var obj = {
name: "John",
test: function() {
alert( this.name );
$("#test").unbind("click", obj.test);
}
}; $("#test").click( jQuery.proxy( obj, "test" ) ); // 以下代码跟上面那句是等价的:
// $("#test").click( jQuery.proxy( obj.test, obj ) ); // 可以与单独执行下面这句做个比较。
// $("#test").click( obj.test );
可以看一下jQuery中的实现(1.6之前的版本):
/* jQuery 源码之 proxy:
使用 apply 形式, 执行回调函数.
*/
jQuery.proxy = function( fn, proxy, thisObject ) {
if ( arguments.length === 2 ) {
// jQuery.proxy(context, name);
if ( typeof proxy === "string" ) {
thisObject = fn;
fn = thisObject[ proxy ];
proxy = undefined; /* 转化结果:
thisObject -> context
fn -> name
proxy -> undefined
*/
}
// jQuery.proxy(name, context);
else if ( proxy && !jQuery.isFunction( proxy ) ) {
thisObject = proxy;
proxy = undefined;
}
}
if ( !proxy && fn ) {
/* 使用 proxy 保证 函数执行时, context 为指定值 */
proxy = function() {
return fn.apply( thisObject || this, arguments );
};
}
// Set the guid of unique handler to the same of original handler, so it can be removed
if ( fn ) {
proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
}
// So proxy can be declared as an argument
return proxy;
}
其实就是平常使用的的call和apply,大部分的时候作为回调使用。
在stackoverflow上有个问题,其中的例子比较典型,供参考:
比如有如下代码:
$('#myElement').click(function() { // In this function, "this" is our DOM element. $(this).addClass('aNewClass'); });
这里的this就是我们的DOM元素。如果我们要在增加class样式之前需要等待一段时间,可能会将代码写成下面这样(注意:有问题的代码):
$('#myElement').click(function() { setTimeout(function() { // Problem! In this function "this" is not our element! $(this).addClass('aNewClass'); }, 1000); });
这里的this就不是我们期望的那个DOM元素了。解决方法就是使用jQuery的$.proxy()了,代码如下:
$('#myElement').click(function() { // ------------------v--------give $.proxy our function, setTimeout($.proxy(function() { $(this).addClass('aNewClass'); // Now "this" is again our element }, this), 1000); // ---^--------------and tell it that we want our DOM element to be the // value of "this" in the function });
我们可以这样来理解上面的代码:
function() { // v--------func is the function we gave to $.proxy func.apply( ctx ); // ----------^------ ctx is the value we wanted for "this" (our DOM element) }
这就体现出来jQuery中$.proxy()的强大功效了。
注意:在jQuery 1.6及之后的版本中,除了上面提到的两种用法之外,proxy还增加了其他两种用法:
jQuery.proxy( function, context [, additionalArguments ] )
jQuery.proxy( context, name [, additionalArguments ] )
具体使用可以参考jQuery手册。
jQuery中$.proxy()的原理和使用的更多相关文章
- jQuery源码:从原理到实战
jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...
- jquery ready方法实现原理 内部原理
jquery ready方法实现原理 内部原理 今天闲来无事研究研究jquery.ready()的内部实现,看JQ的源码一头雾水,由于自己很菜了,于是翻了翻牛人的播客,讲述详细,收获颇多. 先普及一下 ...
- jsonp协议 java服务端、JQuery客户端 简单实现原理
原文链接:https://blog.csdn.net/Activity_Time/article/details/96440806 1. 概述 Jsonp(JSON with Padding) 是 j ...
- Ajax跨域原理及JQuery中的实现
浅析Ajax跨域原理及JQuery中的实现分析 AJAX 的出现使得网页可以通过在后台与服务器进行少量数据交换,实现网页的局部刷新.但是出于安全的考虑,ajax不允许跨域通信.如果尝试从不同的域请 ...
- JSONP原理及jQuery中的使用
JSONP原理 JSON和JSONP JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在浏览器和服务器之间交换信息. JSONP(JSON ...
- jQuery( )方法的构建原理
jQuery中最常用方法的就是jQuery( ),也即$( ). jQuery( )是一个函数调用,调用的结果是返回了一个jQuery实例对象. 编写组件通常的做法是将组件封装成一个对象,需要用的时候 ...
- jQuery中的end()
要说end(),我们就不得不说prevObject. 在jQuery中,每个jQuery对象都有一个prevObject属性 var $p = $('p'); 这个属性是做什么的呢? jQuery内部 ...
- JQuery之proxy实现绑定代理
在javascript中,this指代的对象时常会变化,这会造成程序,混乱,一般做法就是先将this保存在一个变量中,就不怕她变了,我们先看一个小例子 var A = function(){ this ...
- Jquery 扩展方法实现原理
JSONP原理 首先:JSON和JSONP是不一样的概念. JSON是一种数据交换格式,而JSONP是非正式传输协议. 该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回 ...
随机推荐
- [POJ] 2456 Aggressive cows (二分查找)
题目地址:http://poj.org/problem?id=2456 最大化最小值问题.二分牛之间的间距,然后验证. #include<cstdio> #include<iostr ...
- The JRE could not be found.Edit the server and change the JRE location.
之前更改了了一个较低的jdk的版本看了看一个项目的代码,不知所云,然后再改回来, 混乱之中只要启动Tomcat就出现这种错误,还是无法找到JRE,最后如此解决: 在Windows->Prefer ...
- HornetQ
https://github.com/flsusp/http-queue https://github.com/sfr-network-service-platforms/hq-console htt ...
- codechef Prime Distance On Tree(树分治+FFT)
题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...
- Windows通用应用平台
什么是 UWP? 很多程序员都有一个梦想:希望自己开发的软件能够轻而易举的在所有平台上运行,而不是把同样的需求,用不同的技术.工具重新开发才能够运行在所有平台上.这就是跨平台,很多软件从业者都在为这个 ...
- OpenMeetings(3)----启动顺序解析
OpenMeetings系统较大,代码量也不小,如果对前端的OpenLaszlo开发不熟悉的话,刚研究代码时,确实有种丈二和尚摸不着头脑的感觉.一番研究之后,终于初步理清了系统的初步动作流程,具体执行 ...
- 我的Android进阶之旅------>Android拍照小例子
今天简单的学习了一下android拍照的简单实现. 当然该程序是个小例子,非常简单,没有什么复杂的操作,但是可以学习到Android 拍照API流程. 1.在布局文件中添加一个 surfaceView ...
- Hive 11、Hive嵌入Python
Hive嵌入Python Python的输入输出都是\t为分隔符,否则会出错,python脚本输入print出规定格式的数据 用法为先add file,使用语法为TRANSFORM (name, it ...
- ios 计算文字的尺寸
/** * 计算文字尺寸 * @param text 需要计算尺寸的文字 * @param font 文字的字体 * @param maxSize 文字的最大尺寸 */ - (CGSize)sizeW ...
- IOS6和IOS7 显示一样的SearchBar
if (isIOS7) { mySearchBar=[[UISearchBar alloc]initWithFrame:CGRectMake(, , , )]; mySearchBar.autocor ...