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
Understanding $.proxy() in jQuery
提问by Aditya Shukla
回答by user113716
What it ultimately does is it ensures that the value of this
in a function will be the value you desire.
它最终做的是确保this
函数中的值将是您想要的值。
A common example is in a setTimeout
that takes place inside a click
handler.
一个常见的例子是在setTimeout
接受一个内部进行click
处理。
Take this:
拿着这个:
$('#myElement').click(function() {
// In this function, "this" is our DOM element.
$(this).addClass('aNewClass');
});
The intention is simple enough. When myElement
is clicked, it should get the class aNewClass
. Inside the handler this
represents the element that was clicked.
意图很简单。当myElement
被点击时,它应该得到的类aNewClass
。处理程序内部this
表示被单击的元素。
But what if we wanted a short delay before adding the class? We might use a setTimeout
to accomplish it, but the trouble is that whatever function we give to setTimeout
, the value of this
inside that function will be window
instead 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 this
is 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 this
context.
所以这个匿名函数被赋予setTimeout
,它所做的就是在适当的this
上下文中执行我们的原始函数。
回答by jAndy
Without going into greater detail (which would be necessary because this is about Contextin ECMAScript, the this context variableetc.)
无需详细说明(这是必要的,因为这是关于ECMAScript 中的Context、this 上下文变量等)
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 foobar
the object we passed in:
现在我们可以访问foobar
我们传入的对象:
function foobar() {
this.test // === 5
}
This is exactly what jQuery.proxy()
does. It takes a function
and context
(which is nothing else than an object) and links the function by invoking .call()
or .apply()
and returns that new function.
这正是jQuery.proxy()
它的作用。它接受一个function
and 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>