2009-11-24 3 views
5

J'essaie de regrouper certaines fonctions de haut niveau existantes à l'intérieur d'une fermeture (pour éviter de polluer l'espace de noms global) mais je ne suis pas tout à fait de le faire fonctionner. Tout d'abord, tous les JS fonctionne en dehors de ma fonction anonyme, mais une fois que je mets dans la fonction anonyme, j'obtiens une erreur de "crossfade n'est pas ". Est-ce que quelqu'un voit quelque chose de complètement évident que je suis manquant?Fermeture/portée JavaScript/jQuery

Je ne comprends pas pourquoi le setInterval/crossfade fonctionne en dehors de la fonction anonyme mais pas à l'intérieur. Quelque chose dans start() devrait être en mesure de voir vars/fonctions en dehors de start() et il devrait tous être protégé dans la fermeture créée par la fonction anonyme de niveau supérieur? Je n'essaie pas d'accéder à quelque chose dans crossfade(), je suis juste en essayant de l'exécuter.

(function($) { 

    //vars up here that internal functions can access 
    //also using some jquery inside here, so using $ 

    function crossfade() { 
     //body here 
    } 

    //other functions 

    function start() { 
     //body here 

     cInterval = setInterval('crossfade()', 5000); 
    } 

})(jQuery); 

Répondre

7

La méthode setInterval sera lancé dans le cadre de la fenêtre, de sorte que la fonction n'existe Crossfade pas là. Vous devez faire une fonction anonyme de sorte qu'une fermeture est créée qui contient une référence à la fonction:

cInterval = window.setInterval(function() { crossfade(); }, 5000); 
+0

Merci beaucoup cela fonctionne pour moi. –

8

L'utilisation setInterval('crossfade()', 5000); ne crée pas de fermeture - il crée une chaîne à eval() d. Vous devez utiliser une fonction à la place:

setInterval(function() { crossfade(); }, 5000); 
+6

J'utiliserais setInterval (crossfade, 5000); – Nosredna

1

Pour éviter de polluer la portée globale, vous pouvez faire quelques petites choses:

  • Extend jQuery , puisque vous utilisez déjà jQuery. (Utilisez jQuery comme espace de nom.)
  • Créez un seul objet pour stocker vos méthodes. (Créez votre propre espace de noms.)
2

Lorsque setInterval est passé une chaîne, la chaîne est évaluée dans la portée globale. Cela explique pourquoi crossfade n'est pas visible lorsque setInterval se déclenche.

setInterval peut également être transmis une référence de fonction:

setInterval(crossfade, 5000); 

auquel cas votre code fonctionnera comme prévu, puisque crossfade est visible à l'endroit où vous appelez setInterval.

+0

Ouais, j'ai essayé, mais j'ai une erreur à ce sujet ne pas être appelé avec des guillemets. –

+0

Le moyen préféré est sans les guillemets. Quel message d'erreur avez-vous reçu, exactement? – Nosredna