由于提到article帮助你与你的答案,生病尝试从文章中提及的关键点,
在JavaScript中,结合始终是明确的,并且很容易丢失,因此采用这种方法将不参考适当的Ø在所有情况下都会对抗,除非你强迫。总的来说,JavaScript中的绑定并不是一个困难的概念,但它经常被JavaScripters忽略或掩盖,这导致了混淆。
例如:
var john = {
name: 'John',
greet: function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
};
john.greet("Mark");
//=> "Hi Mark, my name is John"
话又说回来,
var john = {
name: 'John',
greet: function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
};
var fx = john.greet;
fx("Mark");
// => "Hi Mark, my name is "
这是用JavaScript 绑定东西,我会称之为“绑定丢失的一个最重要的问题。“只要通过引用而不是 直接通过它的所有者对象访问方法,就会发生 。该方法失去了其隐含的 绑定,并停止引用它的所有者对象,并返回到 其默认值,在这种情况下,它是窗口(所以如果窗口名称属性为 ,那么它将被使用)。
认识结合敏感的代码图案
绑定敏感代码模式涉及传递方法的引用, 这通常通过两种可能的手段发生:或者您是 分配方法作为一个值,或者你传递一种作为 参数的方法(当你考虑 时,它本质上是一样的)。
明确约束
那么我们该如何解决?我们明确地绑定 - 也就是说,我们明确指出 它在被调用时指向该方法内的内容。和 我们该怎么做? JavaScript为我们提供了两种选择:申请和拨打 。
var fx = john.greet;
fx.apply(john, ["Mark"]);
// => "Hi Mark, my name is John"
var fx = christophe.greet;
fx.call(christophe, "Mark");
// => "Hi Mark, my name is John"
所以,我们要的是要坚持结合的方法,使我们得到 绑定方法引用,所以说话的方式。实现这个 的唯一方法是要求我们将原始方法封装在另一个方法中, 将执行应用调用。这里有一个刺在它:
function createBoundedWrapper(object, method) {
return function() {
return method.apply(object, arguments);
};
}
var john = {
name: 'John',
greet: function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
};
var fx = createBoundedWrapper(john, john.greet);
fx("Mark");
// => "Hi Mark, my name is John"
如果你不是JavaScript的过于热衷,上面的代码可能会混淆你 位。这里的想法是,用给定的 对象和方法(其大概属于所述对象)调用createBoundedWrapper将产生一个全新的函数(我们返回的匿名函数)。
你应该甚至绑定?
现在我们已经通过绑定的细节,它只是公平的压力,有时,绑定是矫枉过正。具体来说,有一个 代码模式,其中绑定可以被替换,并且通过使用词法闭包而具有显着的性能收益。 (如果你没有一个明确的 封闭是什么,不要惊慌。)
这里的模式:一种方法中的一些代码依赖于一个匿名 功能通过引用传递工作。该匿名函数需要 访问周围方法的this关键字。例如,假设 一分钟,我们有阵列内的每个迭代器,再次考虑 以下代码:
// ...
processItems: function() {
this.items.each(function(item) {
// Process item…
this.markItemAsProcessed(item);
});
},
// ...
匿名方法可以围绕createBoundedWrapper
被包裹,然后将内this
将指向外范围为this
。
但是,这样的代码并不像看起来那么好。我们看到 实现这样的“绑定参考”要求我们将原始的 方法包装在一个匿名函数中,这意味着调用绑定的 方法引用会导致两个方法调用:我们的匿名包装, 和原始方法。如果任何语言都有一件事情是真的,那就是方法调用是昂贵的。
在这种情况下,我们有访问原始的,期望在我们定义和调用故障 函数(我们传递作为参数传递给每个匿名方法)相同的代码位置这 关键字。 我们可以简单地保存适当的在一个局部变量此引用,并 使用我们的迭代函数内部:
// ...
processItems: function() {
var that = this;
this.items.each(function(item) {
// Process item
that.markItemAsProcessed(item);
});
},
// ...
外卖点
总结一下:
Any member access must be qualified with the object it pertains to, even when it is this.
Any sort of function reference (assigning as a value, passing as an argument) loses the function’s original binding.
JavaScript provides two equivalent ways of explicitly specifying a function’s binding when calling it: apply and call.
Creating a “bound method reference” requires an anonymous wrapper function, and a calling cost. In specific situations, leveraging closures may be a better alternative.
希望这有助于。
规则是,上下文会因地而异。这是一个与jQuery无关的javascript事物,它取决于每个函数的执行方式和/或定义的位置。例如,直接执行'callback'会使用它定义的上下文(它将是'window')来执行它,但是使用'.call()'当然会将上下文更改为您传递给第一个参数的内容, .CALL()'。在ajax成功处理程序中,'this'引用了ajax调用的'context'属性,默认情况下它是传入'$ .ajax'的选项。这发生在使用'.call()'的jQuery内部。 – 2013-05-14 17:13:08
这不是jQuery如何工作的问题,这是* JavaScript *如何工作的问题。每个函数都有自己的上下文('this')。如果您了解如何在JavaScript中处理上下文,那么在jQuery中使用上下文也会更有意义。 – zzzzBov 2013-05-14 17:18:22
好文章http://alistapart.com/article/getoutbindingsituations – shakib 2013-05-14 17:44:48