JavascriptでsetTimer関数にオブジェクト配列を渡したい。
setTimer("foo(object_array)",1000);
このコードでエラーが発生しています。
**注:**申し訳ありません! 私の質問のいくつかの修正: setInterval() 関数で可能ですか。
JavascriptでsetTimer関数にオブジェクト配列を渡したい。
setTimer("foo(object_array)",1000);
このコードでエラーが発生しています。
**注:**申し訳ありません! 私の質問のいくつかの修正: setInterval() 関数で可能ですか。
setTimeoutまたはsetInterval関数の最初のパラメーターで文字列の代わりに無名関数を使用します。
// assuming that object_array is available on this scope
setInterval(function () { foo(object_array); }, 1000);
機能する理由:
内部関数を定義すると、親関数が既に終了した後でも、外部の囲み関数に存在する変数を参照できます。
この言語機能はクロージャーと呼ばれます。
これらの関数の最初の引数として文字列を渡すと、コードは eval関数の呼び出しを使用して内部的に実行されます。これを行うことは、良い習慣とは見なされません。
Eval は JavaScript コンパイラへの直接アクセスを提供し、渡されたコードを呼び出し元の権限で実行します。また、evalを繰り返し/広範囲に使用すると (つまり、setInterval 関数が良い例です)、パフォーマンスの問題が発生します。
CMS(およびこの種の質問に対するほとんどの回答)が対応していないユースケースに対応しているため、ここでルークの回答を拡張します。
timeout を設定するときに引数を関数呼び出しにバインドする必要がある場合、単純な関数エンクロージャーは機能しません。
echo = function (txt) { console.log(txt); };
val = "immediate A";
echo(val);
val = "delayed";
window.setTimeout(function () { echo(val); }, 1000);
val = "immediate B";
echo(val);
Firebug のコンソールを使用していると仮定すると、上記は「即時 A」、「即時 B」、「即時 B」を 1 秒後に出力します。setTimeout 呼び出し時に値をバインドするには、Luke の trap メソッドを使用します。以下は、任意の関数と引数の長さを受け入れるように少し変更します。
echo = function (txt) { console.log(txt); };
trap = function (fn, args) {
return function() {
return fn.apply(this, args);
};
};
val = "immediate A";
echo(val);
val = "delayed";
window.setTimeout( trap(echo, [val]), 1000);
val = "immediate B";
echo(val);
呼び出し元のコンテキストを暗黙的に渡す方法があるかどうかはわかりませんが、「これ」でうまくいかない場合は、コンテキスト引数を受け入れるようにさらに拡張できます。
まず、「setTimeout」です
次に、文字列を渡さないでください。実際の解決策は、コードの残りの部分に依存します。最も堅牢な方法は、スコープをトラップすることです。
var obj_array = something;
function trap(obj)
{
function exec() { foo(obj); }
return exec;
}
setTimeout(trap(obj_array), 1000);
trap は、配列がスコープ内にトラップされている関数を返します。これは一般的な関数ですが、問題に固有のものにするために、単純化できます。
var obj_array = something;
function trap()
{
function exec() { foo(obj_array); }
return exec;
}
setTimeout(trap(), 1000);
あるいは:
var obj_array = something;
function trap()
{
foo(obj_array);
}
setTimeout(trap, 1000);
そして最終的に次のように要約されます。
var obj_array = something;
setTimeout(function() { foo(object_array); }, 1000);
EDIT:私の機能(またはここのバックアップで見つけたそれらの少なくとも1つの繰り返し)
Function.prototype.createDelegate = function(inst, args) {
var me = this;
var delegate = function() { me.apply(inst, arguments); }
return args ? delegate.createAutoDelegate.apply(delegate,args) : delegate;
};
Function.prototype.createAutoDelegate = function() {
var args = arguments;
var me = this;
return function() { me.apply({}, args); }
};
与えられた:
function test(a, b) { alert(a + b); }
利用方法:
setTimeout(test.createAutoDelegate(1, 2), 1000);
または与えられた:
var o = { a:1, go : function(b) { alert(b + this.a); }}
利用方法:
setTimeout(o.go.createDelegate(o,[5]), 1000);
//or
setTimeout(o.go.createDelegate(o).createAutoDelegate(5), 1000);