理解jQuery中的$ .proxy()

时间:2011-02-13 19:27:52

标签: javascript jquery

docs我明白.proxy()会改变作为参数传递的函数的范围。请问有人能更好地向我解释一下吗?我们为什么要这样做?

4 个答案:

答案 0 :(得分:373)

它最终做的是确保函数中this的值将是您想要的值。

一个常见的例子是setTimeout内部click处理程序。

拿这个:

$('#myElement').click(function() {
        // In this function, "this" is our DOM element.
    $(this).addClass('aNewClass');
});

意图很简单。点击myElement后,它应该会获得课程aNewClass。处理程序内部this表示单击的元素。

但是如果我们在添加课程之前想要一个短暂的延迟呢?我们可能会使用setTimeout来完成它,但问题是,无论我们为setTimeout提供什么函数,该函数中this的值都将是window而不是我们的$('#myElement').click(function() { setTimeout(function() { // Problem! In this function "this" is not our element! $(this).addClass('aNewClass'); }, 1000); }); 元件。

$.proxy()

所以我们可以做的是调用this,向它发送函数和我们想要赋值给$('#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 }); 的值,它将返回一个保留该值的函数。 / p>

$.proxy()

因此,在我们为this提供this函数和我们想要的值之后,它返回了一个函数,该函数将确保正确设置.apply()

它是如何做到的?它只返回一个匿名函数,使用this方法调用我们的函数,它允许它显式设置function() { // v--------func is the function we gave to $.proxy func.apply( ctx ); // ----------^------ ctx is the value we wanted for "this" (our DOM element) } 的值。

返回的函数的简化外观可能如下所示:

setTimeout

因此,这个匿名函数被赋予this,它所做的只是使用正确的{{1}}上下文执行我们的原始函数。

答案 1 :(得分:49)

没有详细说明(这是必要的,因为这是关于ECMAScript中的上下文此上下文变量等)

ECMA- / Javascript中有三种不同类型的“上下文”:

  • 全球背景
  • 功能背景
  • eval context

每个代码都在执行上下文中执行。有一个全局上下文,并且可以有许多函数(和eval)上下文的实例。现在有趣的部分:

函数的每次调用都会进入函数执行上下文。函数的执行上下文如下所示:

激活对象
范围链
此值

所以 this 值是一个与执行上下文相关的特殊对象。 ECMA- / Javascript中有两个函数可能会更改函数执行上下文中的 this 值:

.call()
.apply()

如果我们有一个函数foobar(),我们可以通过调用

来更改 this
foobar.call({test: 5});

现在我们可以在foobar中访问我们传入的对象:

function foobar() { 
    this.test // === 5
}

这正是jQuery.proxy()的作用。它需要functioncontext(它只是一个对象)并通过调用.call().apply()来链接该函数并返回该新函数。

答案 2 :(得分:4)

我写过这个函数:

function my_proxy (func,obj)
{
    if (typeof(func)!="function")
        return;

    // If obj is empty or another set another object 
    if (!obj) obj=this;

    return function () { return func.apply(obj,arguments); }
}

答案 3 :(得分:1)

使用“立即调用函数表达式,简称:IIFE”自执行函数可以实现相同的目标:

    $('#myElement').click(function() {  
      (function(el){
         setTimeout(function() {
              // Problem! In this function "this" is not our element!
            el.addClass('colorme');
        }, 1000);
      })($(this)); // self executing function   
    });
.colorme{
  color:red;
  font-size:20px;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

  <div id="myElement">Click me</div>
</body>
</html>