var x = 1;
function foo(x,y=function(){x=2;}){
var x = 3;
y();
console.log(x);
}
foo();
Ce code apparaît dans le livre es6 écrit par le professeur Ruan Yifeng. Le résultat final est 3. La description textuelle dit que le x dans y et le x dans var x = 3 ; ici.
Ensuite, supprimez la var de var x= 3, et vous pouvez afficher 2, ce qui est encore plus incompréhensible. . . J'espère qu'il y a une réponse
Cela implique en fait une portée intermédiaire introduite par les paramètres par défaut de l'ES6. Ruan Yifeng a également manqué ce problème au début, mais bien sûr, c'est correct ici.
Le but du scope intermédiaire est d'éviter que les paramètres par défaut ne soient pollués par les variables de la fonction. L'intention initiale des paramètres par défaut est de permettre aux paramètres d'avoir des valeurs par défaut. Si les variables à l'intérieur de la fonction peuvent être augmentées, alors les paramètres par défaut n'ont aucun sens. Voir l'article pour des explications et des exemples spécifiques.
En repensant à la question,
Il y a trois portées ici. Mark x de l'extérieur vers l'intérieur :
S'il n'y a pas de paramètre x, alors la marque est :
y() modifie le paramètre x de la fonction foo, pas le x global. (Ici, vous pouvez console.log(x) après avoir appelé y() pour constater que le x global est toujours 1.)
Le problème est simple : 1) Lors de l'utilisation de var x = 3, console.log(x in foo ) s'imprime la variable locale x dans foo, et y() modifie uniquement le paramètre x, donc la sortie finale est la variable locale x = 3
2) Lorsque var n'est pas utilisé, tous les x dans foo pointent vers le paramètre x, et y est utilisé () Changez le paramètre x en 2, et enfin affichez 2
La valeur par défaut de
y modifie le x de la variable globale ;
lui a été attribuée.Supprimez la var de var À ce stade, la valeur 2
C'est la différence entre le cycle de vie des variables locales et des variables globales. var x = 3; dans la méthode est une variable locale. Les deux variables ont le même nom dans le corps de la méthode, mais les variables globales. ne sera pas utilisé, donc la sortie est var x = 3; la valeur de x; lorsque vous supprimez la var de var x = 3;, cela signifie qu'il n'y a pas d'autre variable locale définie dans la méthode, la variable globale Donc la la sortie est 2 ;
Tout d'abord, vous devez comprendre la définition de l'opérateur var. Une variable définie avec l'opérateur var deviendra une variable locale dans le périmètre dans lequel la variable est définie, c'est-à-dire si vous utilisez var pour définir un. variable dans une fonction, alors cette variable appartient à la fonction. Une variable locale sera détruite à la sortie de la fonction, et les variables directement définies sans utiliser var deviendront des variables globales.
.Un autre concept que vous devez comprendre est le problème de la chaîne de portée. Lorsque le programme recherche une variable, il recherchera d'abord dans la portée actuelle. Si elle n'est pas trouvée, il recherchera vers le haut dans la chaîne de portée. trouvé après la traversée, il signalera un état indéfini.
Retour au code ci-dessus, utilisez d'abord var pour définir x=1 dans la portée globale ; x appartient à la variable globale, puis définissez la variable locale var x=3 dans la fonction foo ; exécutez la fonction y et modifiez et attribuez-la. la valeur de la variable globale x. À ce moment, x devient 2. N'oubliez pas que la variable globale x est modifiée à ce moment et non la variable locale. La valeur de x est recherchée en interne. Après avoir trouvé x=3, la valeur est affichée. , donc le résultat est 3. Si la var de var x=3 est supprimée, x devient une variable globale. Modifier x revient à attribuer une valeur à x dans la fonction y. À l'heure actuelle, il n'y a qu'une seule variable globale x. Selon l'ordre d'exécution du code, la variable globale Rechercher dans la portée globale À ce stade, X vaut 2, donc le résultat est 2