web-dev-qa-db-ja.com

引用符と括弧がある場合とない場合のsetTimeoutの違い

私はJavaScriptを学んでいます。最近JavaScriptのタイミングイベントについて学びました。 W3SchoolssetTimeoutについて学んだとき、私はこれまで遭遇したことのない奇妙な人物に気付きました。二重引用符を使用してから関数を呼び出しています。

例:

setTimeout("alertMsg()", 3000);

JavaScriptの二重引用符と一重引用符は文字列を意味します。

また、私はそのように同じことができることを見ました:

setTimeout(alertMsg, 3000);

括弧付きの場合は参照しており、括弧なしの場合はコピーしています。引用符とかっこを使用すると、頭がおかしくなります。

setTimeoutを使用する3つの方法の違いを誰かが私に説明できれば嬉しいです。

かっこで

setTimeout("alertMsg()", 3000);

引用符と括弧なし

setTimeout(alertMsg, 3000);

そして3番目は引用符だけを使っています:

setTimeout("alertMsg", 3000);

N.B .: setTimeout参照のより良い情報源は _ mdn _ でしょう。

230
user1316123

setIntervalまたはsetTimeoutを使用する

setTimeoutまたはsetIntervalの最初の引数として関数への参照を渡す必要があります。この参照は、次の形式になります。

  • 無名関数

    setTimeout(function(){/* Look mah! No name! */},2000);
    
  • 既存の機能の名前

    function foo(){...}
    
    setTimeout(foo, 2000);
    
  • 既存の関数を指す変数

    var foo = function(){...};
    
    setTimeout(foo, 2000);
    

    「関数名」とは別に「関数内の変数」を設定することに注意してください。変数と関数名が同じ名前空間を占めていて、互いを上書きする可能性があることは明らかではありません。

引数を渡す

関数を呼び出してパラメータを渡すには、タイマーに割り当てられたコールバック内で関数を呼び出すことができます。

setTimeout(function(){
  foo(arg1, arg2, ...argN);
}, 1000);

ハンドラに引数を渡す別の方法がありますが、 ブラウザ間の互換性はありません

setTimeout(foo, 2000, arg1, arg2, ...argN);

コールバックコンテキスト

デフォルトでは、実行時のコールバックのコンテキスト(タイマーによって呼び出される関数内のthisの値)は、グローバルオブジェクトwindowです。変更したい場合はbindを使用してください。

setTimeout(function(){
  this === YOUR_CONTEXT; // true
}.bind(YOUR_CONTEXT), 2000);

セキュリティ

それは可能ですが、 setTimeoutsetIntervalにstring を渡さないでください。文字列を渡すと、setTimeout()またはsetInterval()eval() に似た機能を使用し、 は文字列をscripts として実行するので、任意で有害な可能性のあるスクリプトの実行が可能になります。

374
Joseph

あなたが書いたsetTimeout関数は実行されていないと思います。 jqueryを使っているのなら、こうすることでjqueryを正しく動作させることができます。

    function alertMsg() {
      //your func
    }

    $(document).ready(function() {
       setTimeout(alertMsg,3000); 
       // the function you called by setTimeout must not be a string.
    });
3
Acil Az

完全にジョセフに同意します。

これはこれをテストするためのフィドルです: http://jsfiddle.net/nicocube/63s2s/ /

フィドルの文脈では、関数はグローバルスコープで定義されていないため、文字列引数は機能しません。

2
Nicocube

あなたが関数の最初のパラメータとして文字列を渡す場合、実際には何が起こりますか

setTimeout('string'number

実行時(ミリ秒単位のnumberの経過後)に評価された最初のパラメーターの値です。基本的には等しい

setTimeout(eval('string')number

これは

関数の代わりに文字列を含めることを可能にする代替構文。これはタイマーが切れるとコンパイルされ実行されます。この構文は、eval()の使用をセキュリティ上のリスクにするのと同じ理由で推奨されません。

だからあなたが参照するサンプルは良いサンプルではありません、そして異なった文脈または単に単純なタイプミスで与えられるかもしれません。

このsetTimeout(something, number)のように呼び出すと、最初のパラメータは文字列ではなく、somethingと呼ばれるものへのポインタです。 somethingが文字列の場合も、評価されます。しかし、それがfunctionであれば、functionは実行されます。 jsbinサンプル

0

かっこで

setTimeout("alertMsg()", 3000); // It work, here it treat as a function

引用符と括弧なし

setTimeout(alertMsg, 3000); // It also work, here it treat as a function

そして3番目は引用符だけを使っています:

setTimeout("alertMsg", 3000); // It not work, here it treat as a string
function alertMsg1() {
        alert("message 1");
    }
    function alertMsg2() {
        alert("message 2");
    }
    function alertMsg3() {
        alert("message 3");
    }
    function alertMsg4() {
        alert("message 4");
    }

    // this work after 2 second
    setTimeout(alertMsg1, 2000);

    // This work immediately
    setTimeout(alertMsg2(), 4000);

    // this fail
    setTimeout('alertMsg3', 6000);

    // this work after 8second
    setTimeout('alertMsg4()', 8000);

上の例では、最初にalertMsg2()関数が直ちに呼び出され(タイムアウトは4秒になりますが、気にする必要はありません)、alertMsg1()(2秒間の待機)、次にalertMsg4()(8秒間の待機)しかし、alertMsg3()は、当事者なしで引用符の中に入れるので文字列として扱われるため、機能しません。

0
Srikrushna Pal
    ##If i want to wait for some response from server or any action we use setTimeOut.

    functionOne =function(){
    console.info("First");

    setTimeout(()=>{
    console.info("After timeOut 1");
    },5000);
    console.info("only setTimeOut() inside code waiting..");
    }

    functionTwo =function(){
    console.info("second");
    }
    functionOne();
    functionTwo();

## So here console.info("After timeOut 1"); will be executed after time elapsed.
Output:
******************************************************************************* 
First
only setTimeOut() inside code waiting..
second
undefined
After timeOut 1  // executed after time elapsed.
0
Avinash Khadsan