由於提到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