2

ユーザーにメッセージを「入力」する関数を実装しようとしていました。「T」-待機-「Th」-待機-「Tha」のようなもの...この関数を思いつきましたが、待機してからすべての文字を一度に更新します(個別に更新するのではなく):

var tu = 'Thank you'
var timing = 1000
for (var i=0; i<=tu.length; i++) {
    setTimeout(function (){input.text(tu.slice(0, i))}, timing)
    timing = timing + 1000
}

しかし、私がこれをやったとき(笑わないでください)、うまくいきました..

setTimeout(function (){input.text('t')}, 400)
setTimeout(function (){input.text('th')}, 800)
setTimeout(function (){input.text('tha')}, 3000)
setTimeout(function (){input.text('than')}, 4000)
setTimeout(function (){input.text('thank')}, 5000)
setTimeout(function (){input.text('thank ')}, 6000)
setTimeout(function (){input.text('thank y')}, 7000)
setTimeout(function (){input.text('thank yo')}, 8000)
setTimeout(function (){input.text('thank you')}, 9000) 

ループがカットアンドペーストの仕事とは異なる動作をしている理由を誰かが明らかにすることはできますか?

4

3 に答える 3

5

これは、JavaScript の奇妙なスコープの例です。は、 の値ではなく、setTimeoutの参照を取得しています。ループはどの実行よりも前に完了するため、すべての はに対して同じ値、つまりを使用します。i iforsetTimeoutssetTimeoutitu.length

これを修正するには、クロージャーを使用する必要があります。

var tu = 'Thank you'
var timing = 1000
for (var i = 1; i <= tu.length; i++) {
    (function (i) {
        setTimeout(function () {
            input.text(tu.slice(0, i))
        }, timing * i);
    })(i);
}

(また、他の人が指摘したように、境界の問題があります。私はに変更i < tu.lengthしましたi <= tu.length。)

これは jsFiddle で実際に確認できます。

于 2013-03-23T02:11:05.420 に答える
2

これはi、関数よりも大きなスコープにあるため、ループから 10 になり、タイムアウトごとに (10 として) 使用されているためです。

setIntervalこれを回避する方法はありますが、この種の動作に使用する方が適切です。

var tu = 'Thank you'
var timing = 1000
var i=0;
var tm=setInterval(function(){
    ++i;
    input.text(tu.slice(0, i));
    if(i>=tu.length){
        clearInterval(tm);
    }
},timing)
于 2013-03-23T02:13:42.957 に答える
1

iループ内にスコープが失われます。i範囲外になったときにアクセスできる関数を作成する必要があります。これが私がそれを行う方法です:

var tu = 'Thank you',
    timing = 1000;

function doPart(i) {
    setTimeout(function () {
        input.text(tu.slice(0, i));
    }, i*timing);
}

function printString() {
    var i;
    for (i=1; i<tu.length; i++) {
        doPart(i);
    }
}

printString();

また、あなたが意味したと思いますtu.slice(0, i+1)。スライスは、開始インデックスから終了インデックスまでを含みますが、終了インデックスは含みません。

于 2013-03-23T02:06:58.863 に答える