簡體   English   中英

在for循環內綁定偵聽器:變量作用域理解錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM