0

誰かがこれに対する簡単な解決策を教えてくれるかどうか疑問に思っていました。

2 つの犬のインスタンスに、吠える + 尻尾を振るという組み合わせを繰り返させたいと考えています。

すべてのロジックが barkNameAndTime 関数内に含まれている場合は問題ありませんが、setTimout を介して wagTail を呼び出すと、コンテキストが失われます。私はJSをあまり書いていないので、クロージャーの知識は少し錆びており、きれいな解決策を見つけることができないようです.

問題は、バルーが吠えたり尻尾を振ったりすることになり、ローラが群衆の中に紛れてしまうことです :)

ありがとうウォリック

<script type="text/javascript">
$(document).ready(function () {
    var zDog1 = new dog("Lola");
    var zDog2 = new dog("Baloo");

    zDog1.bark();
    zDog2.bark();
});

function dog(aName) {
    var name = aName,
        barkNameAndTime = function () {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + " barked @ " + time);
            setTimeout(wagTail, 1000);
        };

        wagTail = function () {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + "  wagged tail @ " + time);
            setTimeout(barkNameAndTime, 1000);
        }

    return {
        bark: barkNameAndTime
    };
}

4

1 に答える 1

3

実装でwagTailは、はグローバル変数(おそらく誤って)であるため、新しいdogオブジェクトを作成するたびに、その1つのグローバル値とコンテキストが置き換えられます。

(1つのセミコロンをコンマに変更して)ローカル変数にすると、機能するはずです。

function dog(aName) {
    var name = aName,
        barkNameAndTime = function () {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + " barked @ " + time);
            setTimeout(wagTail, 1000);
        }, 

        wagTail = function () {
            var time = new Date().getTime();
            $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + "  wagged tail @ " + time);
            setTimeout(barkNameAndTime, 1000);
        }

    return {
        bark: barkNameAndTime
    };
}

ローカル変数の場合、の各コピーはwagTail独自のクロージャーコンテキストを保持します(したがって、同じスタックフレーム内のローカル変数にアクセスします)。グローバル変数の場合、へのすべての呼び出しはwagTail、最後に割り当てられたときのコンテキストと同じコンテキストを持ちます。

参考までに、これは、1つの微妙なタイプミスによって一部が暗黙のグローバル変数になるため、複数行の初期化子がある場合にローカル変数を宣言するこの方法が気に入らない理由の1つです。私はむしろ地元の人々を事前に宣言してから、体の中で彼らに割り当てたいと思います。このエラーが発生する可能性ははるかに低くなります。または、この場合、変数構文を使用する必要はありません。ローカル関数として宣言するだけで済みますbarkNameAndTimewagTailBergiによって追加されたコード例)。

function dog(name) {
    function barkNameAndTime() {
        var time = new Date().getTime();
        $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + " barked @ " + time);
        setTimeout(wagTail, 1000);
    }
    function wagTail() {
        var time = new Date().getTime();
        $('#MyDiv').html($('#MyDiv').html() + "<br />" + name + "  wagged tail @ " + time);
        setTimeout(barkNameAndTime, 1000);
    }

    return {
        bark: barkNameAndTime
    };
}
于 2012-07-18T18:23:52.680 に答える