Javascript 理解 jQuery 中的 $.proxy()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4986329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:05:19  来源:igfitidea点击:

Understanding $.proxy() in jQuery

javascriptjquery

提问by Aditya Shukla

From docsI understand that .proxy()would change the scope of the function passed as an argument. Could someone please explain me this better? Why should we do this?

文档中我了解到这.proxy()会改变作为参数传递的函数的范围。有人可以更好地解释我吗?我们为什么要这样做?

回答by user113716

What it ultimately does is it ensures that the value of thisin a function will be the value you desire.

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

A common example is in a setTimeoutthat takes place inside a clickhandler.

一个常见的例子是在setTimeout接受一个内部进行click处理。

Take this:

拿着这个:

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

The intention is simple enough. When myElementis clicked, it should get the class aNewClass. Inside the handler thisrepresents the element that was clicked.

意图很简单。当myElement被点击时,它应该得到的类aNewClass。处理程序内部this表示被单击的元素。

But what if we wanted a short delay before adding the class? We might use a setTimeoutto accomplish it, but the trouble is that whatever function we give to setTimeout, the value of thisinside that function will be windowinstead of our element.

但是如果我们想要在添加类之前短暂延迟怎么办?我们可能会使用 asetTimeout来完成它,但问题是无论我们给 什么函数setTimeout,该this函数内部的值都将window代替我们的元素。

$('#myElement').click(function() {
    setTimeout(function() {
          // Problem! In this function "this" is not our element!
        $(this).addClass('aNewClass');
    }, 1000);
});

So what we can do instead, is to call $.proxy(), sending it the function and the value we want to assign to this, and it will return a function that will retain that value.

所以我们可以做的是,调用$.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
});

So after we gave $.proxy()the function, and the value we want for this, it returned a function that will ensure that thisis properly set.

所以在我们给出$.proxy()函数和我们想要的值之后this,它返回了一个函数,以确保this正确设置。

How does it do it? It just returns an anonymous function that callsour function using the .apply()method, which lets it explicitly set the value of this.

它是如何做到的?它只是返回一个匿名函数,该函数使用方法调用我们的函数.apply(),这让它显式设置 的值this

A simplified look at the function that is returned may look like:

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

function() {
    // v--------func is the function we gave to $.proxy
    func.apply( ctx );
    // ----------^------ ctx is the value we wanted for "this" (our DOM element)
}

So this anonymous function is given to setTimeout, and all it does is execute our original function with the proper thiscontext.

所以这个匿名函数被赋予setTimeout,它所做的就是在适当的this上下文中执行我们的原始函数。

回答by jAndy

Without going into greater detail (which would be necessary because this is about Contextin ECMAScript, the this context variableetc.)

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

There are three different types of "Contexts" in ECMA-/Javascript:

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

  • The global context
  • Function context
  • eval context
  • 全球背景
  • 函数上下文
  • 评估上下文

Every code is executed in its execution context. There is oneglobal context and there can be many instances of function (and eval) contexts. Now the interesting part:

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

Every call of a function enters the function execution context. An execution context of a function looks like:

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

The Activation Object
Scope Chain
this value

Activation Object
Scope Chain
这个值

So the thisvalue is a special object which is related with the execution context. There are two functions in ECMA-/Javascript which may change the thisvalue in a function execution context:

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

.call()
.apply()

If we have a function foobar()we can change the thisvalue by calling:

如果我们有一个函数,foobar()我们可以通过调用来更改this值:

foobar.call({test: 5});

Now we could access in foobarthe object we passed in:

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

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

This is exactly what jQuery.proxy()does. It takes a functionand context(which is nothing else than an object) and links the function by invoking .call()or .apply()and returns that new function.

这正是jQuery.proxy()它的作用。它接受一个functionand context(它只不过是一个对象)并通过调用.call()or链接该函数.apply()并返回该新函数。

回答by sgv_test

I have written this function:

我写了这个函数:

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); }
}

回答by Legends

The same goal can be achieved using a "Immediately-Invoked Function Expression, short: IIFE" self executing function:

使用“立即调用函数表达式,简称: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>