惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
月光博客
月光博客
AI
AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CXSECURITY Database RSS Feed - CXSecurity.com
WordPress大学
WordPress大学
GbyAI
GbyAI
L
Lohrmann on Cybersecurity
O
OpenAI News
Schneier on Security
Schneier on Security
P
Palo Alto Networks Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
W
WeLiveSecurity
L
LINUX DO - 最新话题
人人都是产品经理
人人都是产品经理
S
Security Affairs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
Arctic Wolf
Recorded Future
Recorded Future
Microsoft Security Blog
Microsoft Security Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
TaoSecurity Blog
TaoSecurity Blog
C
Check Point Blog
Scott Helme
Scott Helme
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Vercel News
Vercel News
The Hacker News
The Hacker News
Y
Y Combinator Blog
Latest news
Latest news
SecWiki News
SecWiki News
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
Webroot Blog
Webroot Blog
Google DeepMind News
Google DeepMind News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cisco Blogs
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
宝玉的分享
宝玉的分享
L
LINUX DO - 热门话题

博客园 - 令狐葱★

【备忘】12306购票必杀技 Github上最受关注的前端大牛,快来膜拜吧! Javascript知识点:IIFE - 立即调用函数 那些开源程序中让人叹为观止的代码 - 3 保持元素纵横比 那些开源程序中让人叹为观止的代码 - 2 单例模式 那些开源程序中让人叹为观止的代码 - 1 浏览器特性判断 浏览器中F5和CTRL F5的行为区别 CR, LF, CR/LF区别与关系 利用 jQuery 克隆 Object Chrome下Failed to load resource问题居然是由于AdBlock WordPress在线安装插件 jQuery中的.height()、.innerHeight()和.outerHeight() jQuery中的attr()和prop() jQuery中的事件绑定函数.bind()、.live()、on()和.delegate() 实现ECMAScript 5中的Object.create()函数和Object.getPrototypeOf() 函数 Javascript全局变量和delete Javascript基类对象原型中有数组的情况 必须关注的25位知名JavaScript开发者 大坑贴:CSS浏览器兼容性问题及bug汇总
jQuery中$.proxy()的原理和使用
令狐葱★ · 2013-04-25 · via 博客园 - 令狐葱★

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手册。