2011-08-16 4 views
1

Comment modifier le code JavaScript ci-dessous afin qu'il évite d'exposer les variables et les fonctions à la portée globale?Évitez d'utiliser des variables globales et des fonctions en Javascript

var nMax = 10; 
var i = 0; 
var step = function(){ 
       //do stuff 
       i += 1; 
       if(i < nMax){ 
           step(); 
       }else{ 
           alert('finished'); 
       } 
} 
step(); 

Idéalement, il serait reconnaissant si la raison derrière elle pourrait être fournie.

Toute idée serait très appréciée!

Répondre

4

envelopper juste dans une fonction anonyme et appeler cette fonction immédiatement:

(function(){ 
    var nMax = 10; 
    var i = 0; 
    var step = function(){ 
        //do stuff 
        i += 1; 
        if(i < nMax){ 
            step(); 
        }else{ 
            alert('finished'); 
        } 
    } 
    step(); 
})(); 

Un autre exemple: http://jsfiddle.net/n5Srd/

+0

D'oh. Battez-moi par * six secondes *. En fait, ma façon d'exposer le nom de la fonction «étape», ce que je pensais était ce que l'OP voulait. YMMV. – Malvolio

+0

De cette façon, je ne peux pas utiliser la fonction 'step' en dehors de la fonction anonyme. – ShankarSangoli

+0

Haha ouais j'ai été rapide sur celui-ci :) Il a demandé comment ne pas exposer la fonction aussi bien. – Paulpro

2

La méthode standard serait

var step = function(){ 
    var nMax = 10; 
    var i = 0; 
    return function() { 
       //do stuff 
       i += 1; 
       if(i < nMax){ 
           step(); 
       }else{ 
           alert('finished'); 
       } 
    }; 
}(); 
step(); 
+0

Cela ne masque pas non plus la fonction de la portée externe. – Paulpro

1

Une alternative à l'utilisation d'un closure: les fonctions sont des objets, vous pouvez donc y attacher des valeurs comme n'importe quel objet:

function step() 
{ 
    step.i++; 

    if (step.i < step.nMax) step(); 
    else alert('finished'); 
} 

step(); 

Ou, utilisez un objet à l'espace de noms de la fonction et les variables:

var stepper = 
{ 
    i: 0, 
    nMax: 10, 
    step: function() 
    { 
     this.i++; 

     if (this.i < this.nMax) this.step(); 
     else alert('finished'); 
    } 
}; 

stepper.step(); 

Et voici une version plus propre de la réponse de @ PaulPRO qui utilise une déclaration de fonction plutôt qu'une expression de fonction:

(function() 
{ 
    var i = 0, 
     nMax = 10; 

    function step() 
    { 
     i++; 

     if (i < nMax) step(); 
     else alert('finished'); 
    } 

    step(); 
})(); 
+0

Vrai (+1). Cependant, il n'y a qu'un seul * objet * "fonction". Ainsi, le comportement peut être ou ne pas être comme désiré ... peut également utiliser 'arguments.callee' pour éviter de spécifier' step' ... –

+0

Vous avez raison (et probablement déjà savoir ce que je vais dire), mais ['arguments.callee' devrait être évité car il existe une alternative plus simple, plus efficace] (https://developer.mozilla.org/fr/JavaScript/Reference/Functions_and_function_scope/arguments/callee). –

+0

Cela ne résout pas le problème de l'OP de cacher la fonction de la portée extérieure.S'il a déjà une fonction appelée step, ou une variable nommée stepper, elle sera en conflit – Paulpro

0

Mettre dans un objet si fn est appelé par ce qui suit: -

var stepHolder = {}; 
stepHolder.step = (function(nMax){ 
var i = 0; 
return function step(){ 
      //do stuff 
      i += 1; 
      if(i < nMax){ 
          step(); 
      }else{ 
          alert('finished'); 
      } 
    };} 
)(10); 

    stepHolder.step(); 
+0

That 3 est nMax et devrait être 10 – QuentinUK

+0

Stack Exchange sites ont cette fonctionnalité fantastique appelée ['edit'] (http://stackoverflow.com/posts/7073061/edit). Vérifiez-le. –

Questions connexes