1

重複の可能性:
ループ内のJavascriptクロージャ-簡単な実用例

phonegapアプリケーションのクロージャに問題があります。フォームの作成方法の説明を含むJSONオブジェクトがあります。これはおおよそのコードです:

for (var i in this.form.elements) {
    var element = this.form.elements[i];
    switch (element.type) {
        // other cases
        case 5:
            var addThumb, photoInput;
            addThumb = function (domId) {
                return function (imgData) {
                    console.log('id: ' + domId);
                    $(domId).attr({src: 'data:image/jpeg;base64,' + imgData});
                }
            }('#thumb-'+element.id);
            photoInput = $('<input>')
                .attr({type: 'button', value: element.name, name: element.type, id: element.id, 'class': 'photobutton'})
                .click(function (filename, cb) {
                    return function() {
                        console.log('taking photo and saving to ' + filename)
                        takePhoto(filename,addThumb)
                    }
                }('photo-'+element.id, addThumb)
            );
            photoThumb = $('<img>').attr({id: 'thumb-'+element.id, 'class': 'thumbnail', src: 'img/target.png'});
            $('#content').append(photoInput, photoThumb);
            break;
    }
}

フォトボタンをクリックすると、カメラが開いて写真が撮られ、ディスクに保存されます。保存されると、addThumbがbase64写真データとともに呼び出され、サムネイル画像が置き換えられます。テストフォームのそれぞれの出力は次のとおりです。

taking photo and saving to file photo-686
id: '#thumb-690

写真を撮るためのクロージャーは機能しますが、addThumbがコールバックとして呼び出されるとdomId、forループを通過した最後のelement.idが表示されます。2つのサムネイルが与えられると、ボタンが押されたかどうかに関係なく、2番目のサムネイルは常に置き換えられます。これはiPhoneとAndroidの両方で発生するため、私が書いた方法に問題があるはずです。私は何を間違えましたか?

4

2 に答える 2

2
takePhoto(filename, addThumb)

ここでは、 「保護」されていcbない変数ではなく、クロージャーの内側から変数を渡す必要があります。addThumb変数名を「保護」するときに変更するのを忘れたようです。

于 2013-01-04T21:03:54.120 に答える
1

問題は、addThumb変数自体がクロージャによって保護されていないことです。element.i作成時のdの値を囲みますが、ループの次の発生時に置き換えられます。したがって、常に最後に作成された関数を呼び出していますaddThumb

各変数を個別に保護しようとする代わりに、以下を囲む1つのクロージャを作成できますelement

for (var i in this.form.elements) {
    var element = this.form.elements[i];
    (function(element){
       switch (element.type) {
       ...
    })(element);
}
于 2013-01-04T20:56:54.320 に答える