function f1(){//2、找到 f1 函数,执行。
var n=999;//3、给变量 n 赋值。
nAdd=function(){n+=1}//9、找到 nAdd ,匿名函数内没有变量 n ,需要去上层查找,n = 999 +1。
function f2(){//5、找到 f2 函数,执行。
alert(n);//6、执行动作。
}
console.log(n);//新加上,测试,不参与执行步骤。
return f2;//4、返回 f2 函数,需要寻找 f2 函数。
}
var result=f1();//1、将 f1函数的返回值赋值给 result 变量,result 也变成函数,需要寻找f1函数。
result(); //7、第一次执行 result 函数,将步骤 6 的执行动作(步骤 6)结果输出,n 等于 999。
nAdd();//8、执行 f1 函数里的全局变量函数 nAdd ,需要寻找 nAdd 函数。
result(); //10、第二次执行 result 函数,将步骤 5 的执行动作(步骤 6)结果输出,此时 n 等于 1000,因为第一次执行 result 函数时,查找了上层的作用域,n 是 999。
nAdd();//11、如果再执行 nAdd 函数,此时 nAdd 这个函数里的 n 是 1000,而 f1 函数的 n 还是 999,也就是说 f1 的变量 n 和 nAdd 的 n 是两个作用域不同的同名变量。
result();
f1();//新加上,测试
/*结果
控制台输出:999
弹窗:999
弹窗:1000
弹窗:1001
控制台输出:999
*/
Je voudrais demander aux seniors de voir si cette compréhension est correcte.
Supplément : peut-on comprendre que lorsque la fermeture est exécutée pour la première fois, elle doit rechercher la variable dans la couche supérieure. Après l'avoir trouvée, la valeur de la variable dans la couche supérieure devient la valeur de la variable de la sous-fonction. , et il n'est pas nécessaire de chercher à nouveau dans la couche supérieure car il a été hérité lors de la première exécution et devient le vôtre.
C'est un peu compliqué. . .
(couvre-visage
------------------------Ajouté à nouveau----------------------- -
Plus je le regarde, plus cela devient déroutant.
Ensuite, ce fut un désastre complet.
À en juger par les résultats de sortie, la première sortie de console et la dernière sortie de console, n de f1 est immuable.
Mais les sous-fonctions ne peuvent-elles pas lire les variables les unes des autres ? Pourquoi l’expression de nAdd affecte-t-elle n de f2 ?
Pour le moment, b et n dans le résultat ne sont pas les mêmes
.b et n dans nAdd sont les mêmes
Le n dans le résultat ne peut pas être modifié
J'ai la même question, j'ai donc copié ma réponse et en ai ajouté d'autres.
var result=f1()
: La fonction f1 renvoie la fonction f2var result=f1()
:f1函数返回了f2函数把返回的f2函数赋值给result全局变量,(f2的作用域链保存到result全局变量中)
result()
:调用result(),这就形成闭包:有权访问另外一个函数作用域中的变量因为在f2中的作用域引用了f1中的n这个局部变量,当f1执行完毕后,垃圾回收机制发现n变量还在被result中引用所以垃圾回收机制不会把n回收释放。
以至于n一直保存在result作用域链中。result的作用域链正常能访问f1中的局部变量n,形成闭包。
nAdd()
:nAdd没有写var所以nAdd是全局变量,在调用nAdd()和result()是一样的都会形成闭包,匿名函数function(){n+=1}的作用域链中有n这个局部变量,所以当nAdd=funtion(){n+=1}时,这个匿名函数的作用域链保存到了全局变量nAdd形成闭包,调用nAdd()作用域链中找到f1局部变量n=999,n+1=1000。
(la chaîne de portée de f2 est enregistrée dans la variable globale de résultat)result()
Attribuez la fonction f2 renvoyée à la variable globale de résultat,result()
: Appelez result(), qui forme une fermeture :nAdd()
: nAdd n'écrit pas var, donc nAdd est une variable globale. L'appel de nAdd() et result() est le même et formera une fermeture. La fonction anonyme function(){. n+=1} Il y a une variable locale n dans la chaîne de portée, donc lorsque nAdd=function(){n+=1}, la chaîne de portée de cette fonction anonyme est enregistrée dans la variable globale nAdd pour former une fermeture, qui est trouvée dans la chaîne de portée en appelant la variable locale nAdd() f1 n=999, n+1=1000.result()
: result() génère 1000nAdd(); Répétez la troisième étape n+1 = 1001
🎜result(); Répétez la quatrième étape et affichez n🎜🎜 🎜🎜f1(); Aucune fermeture n'est formée lorsque f1 est appelé, n est toujours 999, car n est détruit par le mécanisme de récupération de place après chaque exécution de f1, donc var n=999 est à nouveau appelé ici ; Il est 999🎜🎜 🎜 🎜🎜Pourquoi l'expression de nAdd affecte-t-elle n de f2 ? 🎜🎜 En raison de la fermeture, n n'a jamais été détruit. nAdd() a également formé une fermeture et a modifié la valeur de n, donc result() est rappelé plus tard, n n'a pas été détruit et le recyclage a été +1, donc. ce sera l'Influence. 🎜 Enfin, il n'y a pas de fermeture lorsque f1() est appelé, et n a été détruit auparavant. Donc, il affiche toujours a=999;🎜 🎜🎜Ceci n'est que ma compréhension, s'il y a des erreurs, n'hésitez pas à me le faire savoir🎜🎜Je vous suggère de lire ceci
http://www.ruanyifeng.com/blo...
C'est expliqué plus clairement
C'est trop compliqué à dire
Cette fermeture utilise la fonctionnalité de portée statique de js pour obtenir cet effet
Le premier appel à result() :
alert(n); recherche le n1
nAdd(); ajoute également la valeur de n1
Il en va de même pour ceux qui sont derrière
Et le dernier f1();
Lors de l'exécution, var n = 999 ; attribue une valeur à n1
.Le n de console.log(n) est également n1, donc la valeur imprimée est 999
Votre exemple est un peu simple. Vous pouvez regarder un exemple complexe (concentrez-vous sur la description de la portée statique) :
.portée statique