Question

Aujourd'hui, j'ai discuté avec un collègue des fonctions imbriquées en Javascript:

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

Dans cet exemple, les essais indiquent que b n’est pas joignable en dehors du corps de a, tout comme c. Cependant, d est - après avoir exécuté a (). Vous recherchez la définition exacte de ce comportement dans ECMAScript v. 3 standard , je n'ai pas trouvé le libellé exact que je cherchais; Ce que la sec.13 p.71 ne dit pas, est l'objet auquel l'objet fonction créé par l'instruction de déclaration de fonction doit être lié. Est-ce que je manque quelque chose?

Était-ce utile?

La solution

Ceci est une portée statique. Les instructions d'une fonction sont définies dans cette fonction.

Javascript a toutefois un comportement bizarre, à savoir que sans le mot clé var , vous avez sous-entendu une variable globale . C'est ce que vous voyez dans votre test. Votre " d " La variable est disponible car il s’agit d’un global implicite, même si elle est écrite dans le corps d’une fonction.

En outre, pour répondre à la deuxième partie de votre question: une fonction existe dans son étendue déclarée, tout comme une variable.

Note: Vous ne voulez probablement pas de variables globales, en particulier non implicites. Il est recommandé de toujours utiliser le mot-clé var afin d'éviter toute confusion et de tout garder propre.

Note: La norme ECMA n'est probablement pas le lieu le plus utile pour trouver des réponses à propos de Javascript, bien que ce ne soit certainement pas une mauvaise ressource. N'oubliez pas que javascript dans votre navigateur est simplement une implémentation de cette norme. Par conséquent, le document de normes vous donnera les règles suivies (principalement) par les développeurs lors de la construction du moteur javascript. Il ne peut pas offrir d'informations spécifiques sur les implémentations qui vous intéressent, à savoir les principaux navigateurs. Quelques livres en particulier vous donneront des informations très directes sur le comportement des implémentations de javascript dans les principaux navigateurs. Pour illustrer la différence, j'inclurai ci-dessous des extraits de la spécification ECMAScript et un livre sur Javascript. Je pense que vous conviendrez que le livre donne une réponse plus directe.

Voici la spécification de langage ECMAScript :

  

10.2 Saisie d'un contexte d'exécution

     

Chaque appel de fonction et de constructeur   entre dans un nouveau contexte d'exécution, même   si une fonction s'appelle elle-même   récursivement. Chaque retour est un   contexte d'exécution. Une exception levée,   s’ils ne sont pas attrapés, peuvent aussi sortir d’un ou   plus de contextes d'exécution.

     

Quand contrôler   entre dans un contexte d'exécution, la portée   la chaîne est créée et initialisée,   une instanciation variable est effectuée,   et la cette valeur est déterminée.

     

Le   initialisation de la chaîne du scope,   instanciation variable, et la   la détermination de cette valeur dépend   sur le type de code entré.

Voici le Javascript: le guide définitif (5e édition) de O'Reilly :

  

8.8.1 Portée lexicale

     

Les fonctions en JavaScript sont lexicales   plutôt que dynamiquement portée. Ce   signifie qu'ils courent dans le champ d'application de   où ils sont définis, pas la portée   à partir duquel ils sont exécutés. Lorsqu'un   la fonction est définie, la portée actuelle   la chaîne est enregistrée et devient une partie de   l'état interne de la fonction.   ...

Le livre de Douglas Crockford est hautement recommandé pour traiter de ce type de questions:

JavaScript, les bonnes pièces http://oreilly.com/catalog/covers/9780596517748_cat.gif

Javascript, les bons côtés , également de O 'Reilly.

Autres conseils

Si je comprends bien, ces informations sont équivalentes en ce qui concerne la portée:

function a() { ... }

et

var a = function() { ... }

Il semble important de noter que, même si d est créé en tant que "global", il est en réalité créé en tant que propriété de l’objet window. Cela signifie que vous pourriez par inadvertance écraser quelque chose qui existe déjà sur l'objet window ou que votre variable pourrait ne pas être créée du tout. Donc:

function a() {
    d = 'Hello World';
}
alert(window.d); // shows 'Hello World'

Mais vous ne pouvez pas faire:

function a() {
    document = 'something';
}

car vous ne pouvez pas écraser l'objet window.document.

Pour des raisons pratiques, vous pouvez imaginer que tout votre code est exécuté dans un géant avec un bloc (fenêtre) .

Javascript a deux champs d'application. Globale et fonctionnelle. Si vous déclarez une variable dans une fonction à l’aide de la variable " var " mot-clé, il sera local à cette fonction, et toutes les fonctions internes. Si vous déclarez une variable en dehors d'une fonction, sa portée est globale.

Enfin, si vous omettez le mot clé var lors de la première déclaration d'une variable, javascript suppose que vous vouliez une variable globale, où que vous le déclariez .

Donc, vous appelez la fonction a et la fonction a déclare une variable globale d.

...

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

sans être précédé de var , d est global. Faites ceci pour rendre privé:

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   var d = 'Bound to local object.'
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top