2

私はこのJavascript関数を持っています:

function Card(term, def, terms, curTerm) {
    this.term = term;
    this.def = def;
    this.terms = terms;
    this.curTerm = curTerm;

    this.show = function() {
        that = this;
        var html = createCard(that.term, that.def);
        $('body').append(html);
        $('input[type=text]').focus();
        $('.answer').on('click', function(event) {
            event.preventDefault();
            answer = $(this).parent().serializeArray()[0].value;

            // answer correct
            if (that.term === answer) {
                $('.card').addClass('correct');
                $('form').replaceWith('<h2>Correct! ' + that.term + '</h2>');
                setTimeout(function () {that.destroy(terms, curTerm + 1);}, 1500);

            // answer incorrect
            } else {
                $('.card').addClass('incorrect');
                $('form').replaceWith('<h2>Incorrect! ' + that.term + '</h2>');
                setTimeout(function () {that.destroy(terms, curTerm);}, 1500);
            }
        });
    };

私が問題を抱えている行はsetTimeout(function () {that.destroy(terms, curTerm + 1);}, 1500);. もともと私は持っていましたがsetTimeout(that.destroy(terms, curTerm + 1), 1500);、呼び出したばかりのタイムアウトを設定しませんでしたthat.destroy。匿名関数に入れたときにすぐに呼び出されないのはなぜですか? これは閉鎖と関係がありますか?クロージャーを作成する必要があるようですが、確実に知るのに十分なことがわかっていません。

任意の考えをいただければ幸いです。

4

3 に答える 3

6

最初のsetTimeout()呼び出しでは、次のようになります。

that.destroy(terms, curTerm + 1)

関数呼び出し式です。呼び出すパラメータ値のセットを構築するために評価されますsetTimeout()

これを無名関数でラップすると、その (無名の) 関数は呼び出されません。これは、関数呼び出し演算子 (パラメーターの括弧で囲まれたリスト) を接尾辞として付けていないためです。

したがって、次の形式の式

something ( p1, p2, ... pn )

引数リスト内の各パラメーターを評価した後、「何か」によって参照される関数を呼び出し、より大きな式のコンテキストが進むにつれてその値を使用することを意味します。JavaScript では常にそれを意味します。「後で呼び出してほしい関数と、いくつかのパラメーターを渡す」という構文はありません。(現在、それを行う関数.bind()があります — Function プロトタイプには — しかし、特別な構文はありません。)

于 2013-01-16T23:27:34.640 に答える
1

これは、JavaScript 構文の一部にすぎません。

function name() {}関数を宣言してname()呼び出します。構文 を使用して、無名関数をすぐに呼び出すこともできます(function (){})()

また、次のように、無名関数が適切な場所に関数を渡すことができることに注意してください。

setTimeout(that.destroy, 1500)

もちろん、その場合、引数を変更することはできません。

于 2013-01-16T23:28:20.243 に答える
1

JavaScript インタープリターはを確認someFunction(param)すると、すぐにメソッドを呼び出してsomeFunctionパラメーターを渡しますparam。つまり、次の場合:

setTimeout(someFunction(param), 1000);

... setTimeout に someFunction(param) の結果を渡しています。代わりに、次のように someFunction をファーストクラスのメンバーとして渡すことができます。

setTimeout(someFunction, 1000, param);

このようにして、setTimeout に someFunction の定義を渡します。paramこの場合のパスは IE では機能しないことに注意してください。

http://www.helephant.com/2008/08/19/functions-are-first-class-objects-in-javascript/も参照してください。

于 2013-01-16T23:30:49.777 に答える