6

私は現在、このスコープをパラメーター「e」を介してラムダ関数に渡し、次に call() メソッドを使用して「funkyFunction」に渡すよりも良い解決策があるかどうか疑問に思っています

setInterval(function(e){e.funkyFunction.call(e)}, speed, this)

(ちょっとした質問はさておき: javascript のメモリ リークについて読んでいました。ラムダ関数はメモリにどのように影響しますか?最初に定義してvar i = function(e)...から setInterval にパラメータとして渡す方がよいでしょうか?)

4

6 に答える 6

12

私の状況は少し違うかもしれませんが、私がやったことは次のとおりです。

var self = this;
setInterval(function() { self.func() }, 50);

私のシナリオは、コードがクラスメソッド内にあり、「this」バインディングを現在のウィンドウに解決したくないため、正しいスコープを維持する必要があるというものでした。

例えば。setInterval を使用して MyClass.init から MyClass.animate を実行したかったので、このスコープ保持コードを MyClass.init に入れました。

于 2011-02-03T19:26:54.333 に答える
9

ネイティブバインド機能を使用できます。

function Loop() {
    this.name = 'some name for test';
    setInterval( (function(){//wrap the function as object
        //after bind, "this" is loop refference
        console.log(this);
    }).bind(this), 1000 );// bind the object to this (this is Loop refference)
}

var loop = new Loop();

この例をコンソールに貼り付けて結果を確認します

于 2014-01-06T09:03:46.557 に答える
5

外部スコープで定義された変数に単純に依存することの何が問題になっていますか?

(function() { 

    var x = {};
    setInterval(function() {
       funkyFunction.call(x)
    }, speed);

})();
于 2010-08-15T18:15:18.333 に答える
1

同じ質問がありましたが、組み込みのソリューションはないようです。

function setScopedInterval(func, millis, scope) {
    return setInterval(function () {
        func.apply(scope);
    }, millis);
}

利用方法:

function MyClass() {
    this.timer = null;
    this.myFunc = function() { console.log('do some stuff'); };
    this.run = function() {
        this.timer = setScopedInterval(function () { this.myFunc(); }, 1000, this);
    };
    this.stop = function() { clearInterval(this.timer); };
}
var instance = new MyClass();
instance.run(); // will log to console every second
// until this line is called
instance.stop();

これは、実行されるコードの文字列ではなく、実際の関数を渡すユースケースのみを対象としています。

この機能を使用する際のメモリ リークに関する質問についてsetIntervalは、無名関数自体を使用する場合ほど問題はありません。ラムダ内のオブジェクトへの参照を使用する場合、この参照は、無名関数が存在する限り、参照されたオブジェクトをメモリに保持します。への呼び出しで関数が破棄されていると思いますclearInterval

最初に関数を変数に割り当てることによる利点はないと思います。逆に、anon関数が存在する限り、ガベージコレクションされない参照を含む別の変数が作成されます...

于 2013-08-12T08:09:04.507 に答える
0

2 つの重要な違いがあります。

1) タイムアウト関数が変更を追跡できるように、渡されたパラメーターへの参照が必要ですか、それとも渡されたパラメーターのクローンが必要ですか?

2) タイムアウトをキャンセルしたい場合に備えて、タイムアウトへの参照をキャプチャできるようにしますか? (はい!)

// Normal setTimeout: retains a reference to `test` and returns the bad value
var test = 'test: good';
var timer = setTimeout(function() { console.log(test); }, 1000);
test = 'test: bad';

// Test2 receives a clone of `test2` and returns the good value, but does so right away, not on a timeout
var test2 = 'test2: good';
var timer2 = setTimeout((function() { console.log(test2); })(test2), 1000);
test2 = 'test2: bad';

// Test3 receives a clone of `test3` and returns the good value, but doesn't return a reference to the timeout, and can't be canceled
var test3 = 'test3: good';
var timer3 = function(test3) { setTimeout(function() { console.log(test3); }, 1000); }(test3);
test3 = 'test3: bad';

// Test4 receives a clone of `test4` and returns the good value, and correctly returns timeout reference
var test4 = 'test4: good';
var timer4 = function(test4) { return setTimeout(function() { console.log(test4); }, 1000); }(test4);
test4 = 'test4: bad';

// Test5 retains a reference to `test5` and returns the bad value
var test5 = 'test5: good';
var timer5 = setTimeout((function() { console.log(test5); }).bind(test5), 1000);
test5 = 'test5: bad';

// Did we capture references to the timeouts?
console.log(typeof timer);
console.log(typeof timer2);
console.log(typeof timer3);
console.log(typeof timer4);
console.log(typeof timer5);
于 2014-12-01T00:51:00.170 に答える