C'est portée statique. Les instructions d'une fonction sont définies dans cette fonction.
Javascript a un comportement bizarre, mais, ce qui est que sans le mot-clé var, vous avez impliqué une variable globale . C'est ce que vous voyez dans votre test. Votre variable "d" est disponible car elle est implicite globale, bien qu'elle soit écrite dans le corps d'une fonction.
Aussi, pour répondre à la deuxième partie de votre question: Une fonction existe dans n'importe quelle portée, comme une variable.
Sidenote: Vous ne voulez probablement pas de variables globales, en particulier pas celles implicites. Il est recommandé de toujours utiliser le mot-clé var, afin d'éviter toute confusion et de garder tout propre.
Sidenote: La norme ECMA est probablement pas l'endroit le plus utile de trouver des réponses sur Javascript, bien qu'il ne soit certainement pas une mauvaise ressource. Rappelez-vous que javascript dans votre navigateur est juste une implémentation de cette norme, donc le document de normes vous donnera les règles qui ont été (la plupart du temps) suivies par les implémenteurs 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. Il y a quelques livres en particulier qui vous donneront des informations très directes sur le comportement des implémentations javascript dans les principaux navigateurs. Pour illustrer la différence, je vais inclure des extraits ci-dessous à la fois de la spécification ECMAScript, et un livre sur Javascript. Je pense que vous serez d'accord que le livre donne une réponse plus directe.
est ici de la ECMAScript Language Specification:
10,2 Saisie d'un contexte d'exécution
Chaque fonction et constructeur appel entre dans un nouveau contexte d'exécution, même si une fonction est elle-même appelle récursivement. Chaque retour quitte un contexte d'exécution . Une exception lancée, si elle n'est pas interceptée, peut également quitter un ou plusieurs contextes d'exécution.
Lorsque le contrôle pénètre dans un contexte d'exécution, la portée chaîne est créé et initialisé, la variable instanciation est effectuée, et cette valeur est déterminée.
L'initialisation de la chaîne de portée, instanciation variable et la détermination de la cette valeur dépend du type de code étant entré.
est ici de O'Reilly Javascript: The Definitive Guide (5th Edition):
8.8.1 lexicale
Fonctions JavaScript sont lexicalement plutôt que de portée dynamique. Ce signifie qu'ils s'exécutent dans la portée dans qu'ils sont définis, pas la portée à partir de laquelle ils sont exécutés. Lorsqu'une fonction est définie, la chaîne de portée actuelle est enregistrée et devient une partie de l'état interne de la fonction. ...
Hautement recommandé pour couvrir ce genre de questions est le livre de Douglas Crockford:
JavaScript, The Good Parts http://oreilly.com/catalog/covers/9780596517748_cat.gif
Javascript, The Good Parts, également de O'Reilly.
Exactement le droit - en gros 'la fonction a() {}' est équivalente à 'var a = function() {}' (il y a quelques différences sémantiques mineures, mais rien de trop significatif). – olliej
merci, mais où puis-je trouver les assertions suivantes dans la norme ECMAScript (ou est-il manquant?): "Les instructions au sein d'une fonction sont étendues dans cette fonction." Dans mon impression, la sémantique de "var a = function() {}" sont bien définies, mais pas celles de l'instruction "function a() {...}". –
Le standard ECMAScript ne vous donnera que les instructions pour l'implémentation d'ECMAScript, dont Javascript n'est qu'un membre de la famille. Donc, vous ne trouverez pas cette déclaration exacte, mais il y a d'autres ressources qui peuvent vous aider. Voir ma note supplémentaire ci-dessus. – keparo