244 votes

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

Je suis en train d'apprendre JavaScript et j'ai appris récemment l'existence des événements de synchronisation JavaScript. Quand j'ai appris setTimeout à l'adresse W3Schools j'ai remarqué une silhouette étrange que je n'avais jamais rencontrée auparavant. Ils utilisent des guillemets doubles et appellent ensuite la fonction.

Exemple :

setTimeout("alertMsg()", 3000);

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

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

setTimeout(alertMsg, 3000);

Avec les parenthèses, c'est une référence, sans les parenthèses, c'est une copie. Quand j'utilise les guillemets et les parenthèses, ça devient fou.

Je serais heureux si quelqu'un pouvait 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 la troisième est de n'utiliser que des guillemets :

setTimeout("alertMsg", 3000);

N.B. : Une meilleure source pour setTimeout La référence serait MDN .

0 votes

@Jefffrey Bien que j'aime stackoverflow mais qu'y a-t-il de mal à suivre w3cschools ?

5 votes

@Jefffrey ce site w3fools ne dit pas que le contenu est erroné, juste qu'il est peut-être dépassé et qu'il manque des éléments plus récents. Il peut être utilisé comme référence pour (ou pour apprendre) le contenu de base. Je peux comprendre que les gens soient frustrés par la façon dont ils essaient de donner l'impression qu'ils font partie du W3, mais cela n'enlève rien au contenu. C'est bien présenté et facile à lire avec des exemples clairs, parfait pour les novices.

14 votes

@Matthew "Nous pensons, cependant, que W3Schools nuit à la communauté avec des informations inexactes." -- dans les trois premières lignes.

384voto

Joseph the Dreamer Points 43727

Utilisation de setInterval o setTimeout

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

  • Une fonction anonyme

    setTimeout(function(){/* Look mah! No name! */},2000);
  • Le 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 j'ai défini "variable dans une fonction" séparément de "nom de fonction". Il n'est pas évident que les variables et les noms de fonction occupent le même espace de nommage et peuvent s'entrechoquer.

Passage d'arguments

Pour appeler une fonction et passer des paramètres, vous pouvez appeler la fonction à l'intérieur du callback affecté au timer :

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

Il existe une autre méthode pour passer des arguments dans le gestionnaire, cependant il n'est pas compatible avec les différents navigateurs .

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

Contexte de rappel

Par défaut, le contexte de la callback (la valeur de l'option this à l'intérieur de la fonction appelée par le timer) 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é

Même si c'est possible, vous devriez ne pas passer une chaîne de caractères a setTimeout o setInterval . Le passage d'une chaîne de caractères rend setTimeout() o setInterval() utilisent une fonctionnalité similaire à eval() que exécute les chaînes comme des scripts. rendant possible l'exécution arbitraire et potentiellement nuisible de script.

0 votes

J'ai appris que lorsque vous utilisez seulement le nom de la fonction, la fonction est copiée. Alors pourquoi dites-vous dans votre premier exemple que setTumeout foo (fonction) passe la référence de la fonction a i leaned est copiée. et pouvez-vous m'en dire plus s'il vous plaît sur l'eval s'il vous plaît.

42 votes

@user1316123 les fonctions ne sont jamais copiées. il en est de même pour les objets et les tableaux. ils sont passé par référence . vous devriez arrêter de lire w3schools. ils font plus de mal que de bien

4 votes

@JosephtheDreamer fonctions sont objets. "Un nom de fonction" et "Une variable qui se réfère à une fonction" est le même chose. En outre, vous pouvez passer des paramètres à setTimeout directement (pas besoin d'envelopper dans une lambda pour cela (bien que comme vous l'avez dit - les navigateurs plus récents). En outre, le problème n'est pas de laisser les utilisateurs exécuter des scripts (ils peuvent toujours le faire de toute façon), c'est d'accepter l'entrée de autre utilisateurs et en cours d'exécution que comme script. L'utilisateur lui-même peut toujours simplement ouvrir la console et exécuter un JavaScript arbitraire.

3voto

Acil Az Points 88

Je pense que la fonction setTimeout que vous avez écrite n'est pas exécutée. si vous utilisez jquery, vous pouvez la faire fonctionner correctement en faisant ceci :

    function alertMsg() {
      //your func
    }

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

0 votes

Je pense que c'est comme vous, mais le lien w3schools.com/js/js_timing.asp en disant autre chose

0 votes

Si je comprends bien, lorsque j'utilise des parenthèses, je ne peux faire référence qu'à la fonction qui contient la méthode setTimeout, car la fonction n'est disponible qu'à l'échelle locale dans les parenthèses ?

2voto

Nicocube Points 847

Totalement d'accord avec Joseph.

Voici une manipulation pour tester cela : http://jsfiddle.net/nicocube/63s2s/

Dans le contexte du fiddle, l'argument string ne fonctionne pas, à mon avis parce que la fonction n'est pas définie dans la portée globale.

0 votes

w3schools.com/js/js_timing.asp Si vous pouvez entrer le lien s'il vous plaît et voir parce que Joseph dit que c'est dangereux, mais si vous entrez le lien, il fonctionne.

0 votes

Les gars, s'il vous plaît, regardez ça : quirksmode.org/js/this.html ce lien indique qu'un func peut être copié

0 votes

Oui, c'est possible, car les fonctions sont des objets en JS. Le problème avec eval est qu'il évaluera dans le contexte global, et ne parviendra pas à obtenir le contexte local qui se produit avec un fiddle.

1voto

Que se passe-t-il en réalité dans le cas où vous passez une chaîne de caractères comme premier paramètre de la fonction

setTimeout( 'string' , number )

La valeur du premier paramètre est évaluée au moment de l'exécution (après l'exécution). number de millisecondes écoulées). En gros, c'est égal à

setTimeout( eval('string') , number )

C'est

une syntaxe alternative qui vous permet d'inclure une chaîne de caractères 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 celles qui font de l'utilisation de eval() un risque pour la sécurité.

Les échantillons auxquels vous vous référez ne sont donc pas de bons échantillons, et peuvent avoir été donnés dans un contexte différent ou par simple erreur de frappe.

Si vous invoquez comme ceci setTimeout(something, number) le premier paramètre n'est pas une chaîne de caractères, mais un pointeur vers un objet appelé something . Et encore une fois si something est une chaîne - alors elle sera évaluée. Mais si c'est une fonction, alors la fonction sera exécutée. jsbin échantillon

0voto

Avinash Khadsan Points 47
    ##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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X