从文档中我了解到,这.proxy()将改变作为参数传递的函数的范围。有人可以更好地解释一下吗?我们为什么要这样做?
从文档中我了解到,这.proxy()将改变作为参数传递的函数的范围。有人可以更好地解释一下吗?我们为什么要这样做?
Answers:
它最终要做的是确保this函数中的值将是您想要的值。
一个常见的示例是在处理程序setTimeout内部发生的click。
拿着这个:
$('#myElement').click(function() {
// In this function, "this" is our DOM element.
$(this).addClass('aNewClass');
});
目的很简单。当myElement被点击时,它应该得到的类aNewClass。处理程序内部this表示被单击的元素。
但是,如果我们想在添加课程之前稍加延迟怎么办?我们可能使用a 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
});
因此,在提供$.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上下文中执行我们的原始函数。
$.proxy(function () {...}, this)而不是有(function() {...}).call(this)什么价值?有区别吗?
.call您一起立即调用该函数。使用$.proxy,就像Function.prototype.bind返回新函数一样。该新函数具有this永久绑定的值,因此当将其传递给时setTimeout,以后再setTimeout调用该函数时,它仍将具有正确的this值。
无需赘述(这是必要的,因为这与ECMAScript中的Context,this上下文变量等有关)
ECMA- / Javascript中有三种不同类型的“上下文”:
每个代码都在其执行上下文中执行。有一个全局上下文,并且可以有许多功能(和评估)上下文实例。现在有趣的部分:
每次调用函数都会进入函数执行上下文。函数的执行上下文如下所示:
激活对象
范围链
此值
因此,此值是一个与执行上下文相关的特殊对象。ECMA- / Javascript中有两个函数可以在函数执行上下文中更改此值:
.call()
.apply()
如果我们有一个函数,foobar()我们可以通过调用以下方法来更改此值:
foobar.call({test: 5});
现在我们可以访问foobar传入的对象:
function foobar() {
this.test // === 5
}
正是jQuery.proxy()这样。它需要一个functionand context(仅是一个对象),并通过调用.call()or 链接该函数,.apply()然后返回该新函数。
使用“立即调用的函数表达式,简称: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>