1

この関数呼び出しを考えると:

var funcs = obj.getClosures([2, 4, 6, 8], function(x) {
    return x*x;
});

私は次の機能を持っています:

getClosures : function(arr, fn) {
    var funcs = [];
    var array = arr;
    var i = 0;
    var l = array.length;

    (function(i, array) {

        for (; i < l; i++) {
            funcs[i] = function(i, array) {
                return fn(array[i]);
            };
        }

    }(i, array));

    return funcs; 

},

返された配列をループして、配列内の各項目の平方根値を次のように取得できるようにしたいと思います。

for (var i = 0; i < arr.length; i++) {
   funcs[i]();
}

ループのたびに結果: 4, 16, 36, 64

私の funcs 配列は、関連する引数値で簡単に呼び出すことができる各インデックスに関数参照を持つべきではありませんか? どこで私は間違えましたか?

4

2 に答える 2

2

複数の「問題」があります:

ここでは、 IIFE(function(i, array) { ... }(i, array));には何のメリットもありません。削除すると、コードはまったく同じ動作になります。iとの現在の値をキャプチャする場合は、ループarrayに移動する必要があります。for

関数定義が正しくありません。

funcs[i] = function(i, array) {
    return fn(array[i]);
};

関数内では、関数に渡す引数array[i]を参照します。何も渡さない場合、それらは渡され、コードはエラーをスローします。つまり、その定義では、次のように関数を実行する必要があります。undefined

for (var i = 0; i < arr.length; i++) {
   funcs[i](i, array);
}

これは、そもそも関数を生成する目的を無効にします。

i関数が定義されたスコープにアクセスできるクロージャーを作成する場合はarray、同じ名前のパラメーターを定義しないでください。

考えられる解決策:

for (var i = 0, l = array.length; i < l; i++) {
    (function(i) {
        funcs[i] = function() {
            return fn(array[i]);
        };
    }(i));
}

または、次をサポートする環境でコードが実行される場合は、より簡単です.map

getClosures: function(arr, fn) {
    return arr.map(function(v) {
        return function() {
            fn(v);
        };
    });
},

関連する質問:

于 2013-06-29T10:57:53.577 に答える
0

Function.prototype.bindについて読む:

var obj = {
getClosures : function(arr, fn) {
     var funcs = [];
    var array = arr;
    var i = 0;
    var l = array.length;

    (function(i, array) {

        for (; i < l; i++) {
            funcs[i] = function(i, array) {
                return fn(array[i]);
            }.bind(this,i,array);
        }

    }(i, array));

    return funcs; 

}
}

var funcs = obj.getClosures([2, 4, 6, 8], function(x) {
    return x*x;
});

for (var i = 0; i < funcs.length; i++) {
   console.log(funcs[i]());
}

出力:

4
16
36
64

javascript 1.8.5 (firefox 4) 以降で動作します。他のブラウザーについてはわかりませんが、古いバージョンの実装があります (古いブラウザーでも動作するはずです)。

于 2013-06-29T11:11:10.623 に答える