Javascript – différence entre l'espace de noms et la fermeture?

Dans Javascript, quelle est la différence entre un espace de noms et une fermeture? Ils semblent très semblables à moi.

MODIFIER

Plus précisément, cet article traite des espaces de noms et des fermetures, et a des phrases comme

Maintenant, nous allons toujours avoir des situations où nous voulons déclarer des variables qui ne correspondent pas naturellement à une structure d'objet avec espace de noms. Mais nous ne voulons pas que ces variables aient une portée globale. C'est là que les fonctions d'auto-appel entrent.

Il continue à donner ce qui ressemble beaucoup à une fermeture, en tant que «espace de noms d'objet». Il me semble que l'espace de noms est une fermeture … mais peut-être que ce n'est pas …? Aidez-moi?

Un espace de noms est essentiellement un Object sans aucune propriété intéressante dans laquelle vous utilisez des objets, de sorte que vous ne disposez pas d'un tas de variables avec des noms similaires et / ou conflictuels fonctionnant autour de votre portée. Ainsi, par exemple, quelque chose comme

 MyNS = {} MyNS.x = 2 MyNS.func = function() { return 7; } 

Une fermeture est quand une fonction "conserve" les valeurs de variables qui ne sont pas définies dans celle-ci, même si ces variables sont hors de portée. Prenez ce qui suit:

 function makeCounter() { var x = 0; return function() { return x++; } } 

Si je laisse c = makeCounter() , puis appel à plusieurs reprises c() , j'aurai 0, 1, 2, 3, ... C'est parce que la portée de la fonction anonyme interne qui makeCounter définit 'se referme' sur x , donc il en fait référence même si x est hors de portée.

Notamment, si je fais alors d = makeCounter() , d() commencera à compter de 0. Ceci est dû au fait que c et d obtiennent différentes instances de x .

Un espace de noms est généralement une méthode consistant à mettre toutes vos variables globales en tant que propriétés sous une seule variable globale principale, ce qui ne fait qu'ajouter une nouvelle variable globale véritablement supérieure. Il empêche la pollution de l'espace de noms global et réduit les risques de conflit avec d'autres variables globales.

Et l'exemple d'un espace de noms:

 var YUI = {}; YUI.one = function(sel) {...}; YUI.two = function(sel) {...}; YUI.three = function(sel) {...}; 

Il existe un nouvel élément dans l'espace de noms global YUI niveau supérieur, mais il existe plusieurs éléments accessibles partout dans le monde via l'objet de l'espace de noms YUI.

Une fermeture est un bloc fonctionnel qui dure au-delà de la finition normale de l'exécution de la fonction en raison de références durables aux parties internes de la fonction.

 function doSometing() { var x = 10; setTimer(function() { // this gets called after doSomething() has finished executing // but because of the function closure, the variables // inside of the parent scope like x are still accessible x += 10; }, 1000); } 

À partir de http://jibbering.com/faq/notes/closures/ :

Une fermeture est formée en renvoyant un objet de fonction qui a été créé dans un contexte d'exécution d'un appel de fonction de cet appel de fonction et en attribuant une référence à cette propriété interne à une propriété d'un autre objet. Ou en attribuant directement une référence à un tel objet de fonction, par exemple, à une variable globale, une propriété d'un objet globalement accessible ou un objet passé par référence comme argument à l'appel de fonction externe.

Les espaces de noms ne sont qu'une convention, des objets créés pour éviter d'encombrer la portée globale avec des variables.