[英]Binding listeners inside of a for loop : variable scope miscomprehension
我有一個可變范圍的問題,我不明白為什么會這樣以及如何擺脫它:
var items = ['foo', 'bar'];
for (var index in items) {
var item = items[index];
var selector = '.'+item+'-class';
$(selector).bind('click', function() {
console.log("class: "+$(this).attr('class'));
console.log("selector: "+selector);
console.log("item: "+item);
});
}
認為此代碼可以通過以下HTML自身執行:
<div class="foo-class">Foo</div>
<div class="bar-class">Bar</div>
單擊“ Foo”會在第一行中顯示正確的類(即“ foo-class”),但是選擇器和其后的項目名稱與bar相關。 我認為問題在於循環的第二次迭代會重置第一個循環中使用的變量。
我認為循環內部的聲明應在此級別明確聲明其范圍。 我錯了嗎 ? 為什么呢 我該如何解決?
我不是要尋求一種解決方法,我想要一些干凈的東西以及對javascript變量作用域機制的更好理解。
這是jsfiddle 。
謝謝 !
這是您更新的小提琴示例。
var items = ['foo', 'bar'];
for (var index in items) {
(function() {
var item = items[index];
var selector = '.' + item + '-class';
$(selector).bind('click', function() {
console.log("class: " + $(this).attr('class'));
console.log("selector: " + selector);
console.log("item: " + item);
});
})();
}
創建匿名函數將為每個定義的變量定義一個新范圍
提示:嘗試創建一個單獨的函數來執行綁定,只是為了使您的代碼更整潔。
這些for循環總是相同的(用Google搜索)。 JavaScript沒有塊作用域,而是函數作用域,因此單擊一個項目時, 一個變量selector
具有上一次循環運行后的值(與變量item
相同)。
要解決該問題,您需要在循環中另外一個閉包,該閉包將變量存儲在其自己的范圍內。 這意味着您需要為每次循環運行執行一個函數。
問題不僅僅與可變范圍有關。 匿名函數在觸發click事件時運行, 而不是在循環中定義時運行。 請考慮以下內容,這些內容在功能上與您的示例相同:
var items = ['foo', 'bar'];
for (var index in items) {
var item = items[index];
var selector = '.'+item+'-class';
$(selector).bind( 'click', test );
}
function test() {
console.log("selector: "+selector);
}
這(希望)演示了正在發生的事情:函數中的全局變量selector
在調用函數時在兩種情況下都是相同的(“ bar”)。
var items = ['foo', 'bar'];
for (var index in items) {
(function(i){
var item = items[i];
var selector = '.'+item+'-class';
$(selector).bind('click', function() {
console.log("class: "+$(this).attr('class'));
console.log("selector: "+selector);
console.log("item: "+item);
});
})(index);
}
Vars“選擇器”和“項目”是對存儲值的位置的引用,當您單擊htl元素之一時,這兩個值就是最后一個循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.