Pourquoi la variable n n'est-elle pas réinitialisée ?
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
Expliquez que la variable n est une variable globale. La variable n est-elle promue en variable globale dans f2 ?
Étant donné que js créera une pile pour chaque appel de fonction, les fonctions au sein de la fonction peuvent également accéder à cette pile.
Tout d'abord, vous pouvez appeler
nAdd
car vous n'avez pas ajoutévar
, ce qui équivaut à définir unnAdd
dans la portée globale lorsque le La fonction est appelée, si vous ajoutezvar
et écrivez comme ceci, une erreur sera signalée.nAdd
,是因为你没加var
,等于是在函数调用时定义了一个全局作用域下的nAdd
,你加上var
再这么写会报错。你的
Votrevar result=f1();
调用了函数f1
,也就创建了一个栈,保存了n=999
,并返回了f2
。之后你再怎么调用result()
,其实都是在调用同一个f2
,而这个f2
引用的外部栈,自然还是第一次调用f1
时候创建的那个。同样的nAdd
var result=f1();
appelle la fonctionf1
, qui crée une pile, enregistren=999
et renvoief2
. Peu importe comment vous appelezresult()
après cela, vous appelez en fait le mêmef2
, et la pile externe référencée par cef2
est naturellement le troisième. Celui créé lorsquef1
est appelé une fois. Bien que le mêmenAdd
agisse globalement, il accède également aux données de la même pile.Dans ce code, le résultat est en fait la fonction de fermeture f2. Il a été exécuté deux fois, la première fois, la valeur était de 999, la deuxième fois, la valeur était de 1 000. Cela prouve que la variable locale n dans la fonction f1 est toujours stockée en mémoire et n'est pas automatiquement effacée après l'appel de f1.
Pourquoi cela se produit-il ? La raison en est que f1 est la fonction parent de f2 et que f2 est affecté à une variable globale, ce qui fait que f2 est toujours en mémoire, et l'existence de f2 dépend de f1, donc f1 est toujours en mémoire et ne sera pas supprimé. une fois l'appel terminé, recyclé par le mécanisme de récupération de place (garbage collection).
Une autre chose à noter dans ce code est la ligne "nAdd=function(){n+=1}". Tout d'abord, le mot-clé var n'est pas utilisé avant nAdd, donc nAdd est une variable globale, pas une variable locale. Deuxièmement, la valeur de nAdd est une fonction anonyme, et la fonction anonyme elle-même est également une fermeture, donc nAdd est équivalent à un setter, qui peut opérer sur des variables locales à l'intérieur de la fonction en dehors de la fonction.
http://www.ruanyifeng.com/blo...
Non
n
被提升为全局变量了,这就是闭包。。。。是
nAdd
是全局变量。nAdd
和result
中涉及的n
都是var n = 999
那个n
,而没有全局的n
http://zonxin.github.io/post/...
var nAdd = ... Si vous réessayez, vous saurez pourquoi
S'il n'y a pas de déclaration var, elle sera promue en variable globale
La variable n n'est pas une variable globale. Le simple fait de l'écrire ainsi empêche la libération de la mémoire de n
.La fonction f2 a une référence persistante à la variable locale n dans la fonction f1. Après le retour de f2, n ne sera pas libéré, et nAdd, en tant que fonction globale, peut bien sûr opérer sur n
n est toujours une variable locale, car l'opération de la variable locale n est toujours effectuée dans la fonction f1. nAdd() est une fonction globale lorsqu'elle est exécutée, n dans la portée à laquelle elle appartient sera augmenté de 1
.var result=f1(); Lorsqu'elle est appelée, une fonction interne f2 est renvoyée et la variable n de la fonction externe est référencée En raison du mécanisme de récupération de place, lorsque f1 est terminé. n n'a pas été recyclé Lorsque result() est exécuté pour la deuxième fois, n devient 1000
nAjouter une variable globale, aucune var n'est ajoutée, c'est donc la portée globale
n est une variable locale
var result=f1()
: La fonction f1 renvoie la fonction f2Attribuez la fonction f2 renvoyée à la variable globale de résultat,
var 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。result()
(le rôle de f2 La chaîne de domaines est enregistrée dans la variable globale de résultat)
Étant donné que la portée dans f2 fait référence à la variable locale n dans f1, lorsque f1 est exécuté, le mécanisme de récupération de place constate que la variable n est toujours référencée dans le résultat, donc le mécanisme de récupération de place ne libérera pas n.result()
: Appelez result(), qui forme une fermeture : A le droit d'accéder aux variables dans une autre portée de fonctionPour que n soit toujours enregistré dans la chaîne de portée des résultats. La chaîne de portée du résultat peut normalement accéder à la variable locale n dans f1, formant une fermeture. #🎜🎜##🎜🎜# #🎜🎜##🎜🎜#
nAdd()
: nAdd n'écrit pas var, donc nAdd est une variable globale Lors de l'appel de nAdd() et result(), une fermeture sera formée et le. fonction anonyme function( )(n+=1} a la variable locale n dans la chaîne de portée, donc lorsque nAdd=funtion(){n+=1}, la chaîne de portée de cette fonction anonyme est enregistrée dans la variable globale nAdd pour former un fermeture, et nAdd( ) a trouvé la variable locale f1 n=999, n+1=1000 dans la chaîne de portée. #🎜🎜##🎜🎜# #🎜🎜##🎜🎜#result()
: result() affichera 1000#🎜🎜##🎜🎜# #🎜🎜# #🎜🎜##🎜🎜# C'est juste ma compréhension. S'il y a une erreur, veuillez la signaler #🎜🎜##🎜🎜#n n'est pas une variable globale, c'est une fermeture. Pourquoi n change-t-il ? Parce que vous n'avez pas écrit var devant votre nAdd et que la valeur par défaut est global, mais votre fonction est définie dans la fermeture, et la portée, etc., est toutes à l'intérieur.