web-dev-qa-db-fra.com

Différence entre setTimeout avec et sans guillemets et parenthèses

J'apprends le JavaScript et j'ai récemment appris les événements de chronométrage JavaScript. Quand j’ai appris setTimeout sur W3Schools , j’ai remarqué une figure étrange que je n’avais jamais vue auparavant. Ils utilisent des guillemets doubles, puis appellent la fonction.

Exemple: 

setTimeout("alertMsg()", 3000);

Je sais que les guillemets simples et doubles en JavaScript signifient une chaîne.

Aussi j'ai vu que je peux faire la même chose comme ça:

setTimeout(alertMsg, 3000);

Avec les parenthèses, il fait référence, sans les parenthèses, il est copié. Quand j'utilise les guillemets et les parenthèses, ça devient fou.

Je serai heureux si quelqu'un peut m'expliquer la différence entre ces trois façons d'utiliser setTimeout:

Avec les parenthèses:

setTimeout("alertMsg()", 3000);

Sans les guillemets et les parenthèses: 

setTimeout(alertMsg, 3000);

Et le troisième utilise uniquement des guillemets: 

setTimeout("alertMsg", 3000);

NB: Une meilleure source pour setTimeout référence serait MDN .

227
user1316123

Utilisation de setInterval ou setTimeout

Vous devez passer une référence à une fonction en tant que premier argument de setTimeout ou setInterval. Cette référence peut être sous la forme de:

  • Une fonction anonyme

    setTimeout(function(){/* Look mah! No name! */},2000);
    
  • Un nom d'une fonction existante 

    function foo(){...}
    
    setTimeout(foo, 2000);
    
  • Une variable qui pointe vers une fonction existante

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

    Notez que je définis "variable dans une fonction" séparément de "nom de la fonction". Il n'est pas évident que les variables et les noms de fonction occupent le même espace de nom et puissent se chevaucher.

Passer des arguments

Pour appeler une fonction et transmettre des paramètres, vous pouvez appeler la fonction à l'intérieur du rappel affecté au temporisateur:

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

Il existe une autre méthode pour transmettre des arguments au gestionnaire, cependant ce n'est pas compatible avec tous les navigateurs .

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

Contexte de rappel

Par défaut, le contexte du rappel (la valeur de this dans la fonction appelée par le minuteur) lorsqu'il est exécuté est l'objet global window. Si vous souhaitez le modifier, utilisez bind.

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

Sécurité

Bien que cela soit possible, vous devriez ne pas transmettre de chaîne } à setTimeout ou setInterval. Le passage d'une chaîne oblige setTimeout() ou setInterval() à utiliser une fonctionnalité similaire à eval() that exécute des chaînes en tant que scripts _, rendant possible l'exécution de scripts arbitraires et potentiellement dangereux. 

370
Joseph

je pense que la fonction setTimeout que vous écrivez n'est pas en cours d'exécution. Si vous utilisez jquery, vous pouvez le faire fonctionner correctement en procédant comme suit: 

    function alertMsg() {
      //your func
    }

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

Totalement d'accord avec Joseph.

Voici un violon pour tester ceci: http://jsfiddle.net/nicocube/63s2s/

Dans le contexte du violon, l'argument chaîne ne fonctionne pas, à mon avis, car la fonction n'est pas définie dans la portée globale.

2
Nicocube

Que se passe-t-il en réalité si vous passez chaîne comme premier paramètre de fonction?

setTimeout ('string', number)

est la valeur du premier paramètre obtenu lorsqu'il est temps de s'exécuter (après le passage de numberde milisecondes). Fondamentalement, il est égal à

setTimeout (eval('string'), number)

C'est

une syntaxe alternative qui vous permet d'inclure une chaîne au lieu d'une fonction, qui est compilée et exécutée à l'expiration du délai. Cette syntaxe n'est pas recommandée pour les mêmes raisons que l'utilisation de eval () pose un risque pour la sécurité.

Ainsi, les échantillons auxquels vous faites référence ne sont pas de bons échantillons et peuvent être donnés dans un contexte différent ou simplement une faute de frappe.

Si vous appelez comme ceci setTimeout(something, number), le premier paramètre n'est pas une chaîne, mais un pointeur sur un élément appelé something. Et encore une fois si something est une chaîne - alors elle sera évaluée. Mais s'il s'agit d'une fonction, celle-ci sera exécutée. échantillon jsbin

0
Vitaliy Markitanov

Avec les parenthèses:

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

Sans les guillemets et les parenthèses:

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

Et le troisième utilise uniquement des guillemets:

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);

Dans l'exemple ci-dessus, le premier appel de la fonction alertMsg2 () est immédiatement (nous donnons le délai d'expiration 4S mais cela ne le dérange pas) après ce message alertMsg1 () (A. temps d'attente de 8 secondes) mais alertMsg3 () ne fonctionne pas car nous le plaçons entre guillemets sans parties donc c'est traité comme une chaîne.

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