簡體   English   中英

在這種情況下 JavaScript 閉包是如何工作的?

[英]How does JavaScript closure work in this case?

在這種情況下 JavaScript 閉包如何工作,更具體地說:最后的(i)是做什么的?

for(var i = 0; i < 10; i++) {
    (function(e) {
        setTimeout(function() {
            console.log(e);  
        }, 1000);
    })(i);
}

我也試圖在我的代碼中實現它,但似乎我沒有做對

for (var i=0; i < len; i++) {

    var formID = document.forms["form-" + i];
    $(formID).bind("submit", validate);

    $(formID).bind("change", function(i){
        var divI = '#ind-' + i;
        $(divI).css("background-color","green");
    })(i);
}

這是一種用於圍繞變量創建局部作用域的模式。 如果沒有使用它,那么每次調用console.log(i)都會在 for 循環完成后記錄i (10) 的值。

for(var i = 0; i < 10; i++) {
    // create new function
    (function(e) {
        // log each counter after 1 second.
        setTimeout(function() {
            console.log(e);  
        }, 1000);
    // execute it with the counter
    })(i); 
}

以上與此相同。

function foobar(e) {
    setTimeout(function() {
         console.log(e);
    }, 1000);
}

for (var i = 0; i < 10; i++) {
    (
        foobar
    )(i);
}

這里真正的問題是在循環中創建函數。 不要這樣做:)

你的代碼

for (var i=0; i < len; i++) {

    var formID = document.forms["form-" + i];
    $(formID).bind("submit", validate);
    // create a full closure around the block of code
    (function() {
        $(formID).bind("change", function(i){
            var divI = '#ind-' + i;
            $(divI).css("background-color","green");
        })//(i); Don't call (i) here because your just trying to execute the 
        // jQuery element as a function. You can't do this, you need to wrap 
        // an entire function around it.
    })(i);
}

但這是錯誤的,您想將這項工作委派給其他人。

function makeGreen(form, i) {
    $(form).change(function() {
         $("#ind-"+i).css("background-color", "green");
    });
}

for (var i=0; i < len; i++) {
    var formID = document.forms["form-" + i];
    $(formID).bind("submit", validate);
    // call a helper function which binds the change handler to the correct i
    makeGreen(formID, i);
}

如果你想變得聰明一點,你可以去掉這些匿名函數

function makeGreen() {
     var divId = $(this).data("div-id");
     $(divId).css("background-color", "green");
}

for (var i=0; i < len; i++) {
    $(document.forms["form-" + i])
        .bind("submit", validate)
        // store i on the form element
        .data("div-id", "#ind-" + i)
        // use a single event handler that gets the divId out of the form.
        .change(makeGreen);
}

編輯

( // contain the function we create.
    function(parameterA) {
         window.alert(parameterA);
    }
) // this now points to a function
("alertMessage"); // call it as a function.

是相同的

( // contain the window.alert function
    window.alert
) // it now points to a function
("alertMessage"); // call it as a function

雖然不是對關閉問題的直接回答,但這是我對這個問題的看法。

我會重新編寫邏輯以避免需要關閉(因為它的要求似乎過於復雜

表單命名有規律這一事實使事情變得非常容易

$('form[id^="form-"]').submit(validate)
     .change(function(){
          var divI = '#ind-' + this.id.replace('form-','');
          $(divI).css("background-color","green");
     });

演示http://jsfiddle.net/gaby/q8WxV/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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