setTimeout()グローバル スコープで文字列パラメータを実行するため、 の値thisも引数も存在しなくなりますcaller。これは、setTimeout で文字列パラメーターを使用しない多くの理由の 1 つです。このような実際の JavaScript 関数参照を使用すると、それに応じて渡される引数を取得するのは非常に簡単な問題です。
function mve(caller){
caller.style.position = "relative";
caller.style.left = (caller.style.left+20) +'px';
setTimeout(function() {
mve(caller)
}, 2000);
}
質問の 2 番目の部分では、caller.style.left単位20pxを追加20すると20px20、ブラウザが理解できる値ではないため、何も起こりません。そこから実際の数を解析し、その数に 20 を追加してから、次のように単位を追加する必要があります。
function mve(caller){
caller.style.position = "relative";
caller.style.left = (parseInt(caller.style.left), 10) +20) + 'px';
setTimeout(function() {
mve(caller)
}, 2000);
}
この機能に欠けているのは、繰り返しを止める方法です。あなたが今持っているように、それは永遠に続きます。次のような反復回数を渡すことをお勧めします。
function mve(caller, iterationsRemaining){
caller.style.position = "relative";
caller.style.left = (parseInt(caller.style.left), 10) +20) + 'px';
if (--iterationsRemaining) > 0) {
setTimeout(function() {
mve(caller, iterationsRemaining)
}, 2000);
}
}
また、これが実際には再帰関数ではないことに興味があるかもしれません。これは、mve()関数が呼び出しsetTimeout()てすぐに終了するためです。しばらくしてから次の反復を実行し、複数の関数呼び出しのスタック フレームに蓄積がないため、実際の再帰はありませんsetTimeout()。mve()コードを見ると再帰のように見えますが、技術的にはそうではありません。