recherche

Maison  >  Questions et réponses  >  le corps du texte

Des questions sur les fermetures javascript ?

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 ?

高洛峰高洛峰2827 Il y a quelques jours991

répondre à tous(9)je répondrai

  • 给我你的怀抱

    给我你的怀抱2017-05-18 10:52:47

    É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 un nAdd dans la portée globale lorsque le La fonction est appelée, si vous ajoutez var et écrivez comme ceci, une erreur sera signalée. nAdd,是因为你没加var,等于是在函数调用时定义了一个全局作用域下的nAdd,你加上var再这么写会报错。

    你的var result=f1();调用了函数f1,也就创建了一个栈,保存了n=999,并返回了f2。之后你再怎么调用result(),其实都是在调用同一个f2,而这个f2引用的外部栈,自然还是第一次调用f1时候创建的那个。同样的nAdd

    Votre var result=f1(); appelle la fonction f1, qui crée une pile, enregistre n=999 et renvoie f2. Peu importe comment vous appelez result() après cela, vous appelez en fait le même f2, et la pile externe référencée par ce f2 est naturellement le troisième. Celui créé lorsque f1 est appelé une fois. Bien que le même nAdd agisse globalement, il accède également aux données de la même pile.

    Donc, ce n'est pas que n est promu en variable globale parce que nAdd est une variable globale, mais que la fonction pointée par nAdd et la fermeture que vous retournez accèdent essentiellement aux mêmes données.

    Vous pouvez essayer de le réécrire comme 🎜
    function f1(){
        var n=999;
        nAdd=function(){n+=1}
        function f2(){
          alert(n);
        }
        return f2;
      }
    
      f1()(); // 调用f1,创建了一个栈,栈内n=999,创建了一个匿名函数,返回了一个闭包。
      nAdd(); // 调用了那个匿名函数
      f1()(); // 又调用f1,又创建了一个栈,栈内n=999,创建了另一个匿名函数,返回了另一个闭包。

    répondre
    0
  • 我想大声告诉你

    我想大声告诉你2017-05-18 10:52:47

    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...

    répondre
    0
  • ringa_lee

    ringa_lee2017-05-18 10:52:47

    Non n 被提升为全局变量了,这就是闭包。。。。
    nAdd是全局变量。
    nAddresult中涉及的n 都是 var n = 999那个n,而没有全局的n

    http://zonxin.github.io/post/...

    répondre
    0
  • 仅有的幸福

    仅有的幸福2017-05-18 10:52:47

    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

    .

    répondre
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-18 10:52:47

    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

    répondre
    0
  • ringa_lee

    ringa_lee2017-05-18 10:52:47

    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

    .

    répondre
    0
  • 阿神

    阿神2017-05-18 10:52:47

    • 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

    répondre
    0
  • 黄舟

    黄舟2017-05-18 10:52:47

    1. var result=f1() : La fonction f1 renvoie la fonction f2
      Attribuez la fonction f2 renvoyée à la variable globale de résultat, var result=f1():f1函数返回了f2函数
      把返回的f2函数赋值给result全局变量,(f2的作用域链保存到result全局变量中)

    2. result():调用result(),这就形成闭包:有权访问另外一个函数作用域中的变量
      因为在f2中的作用域引用了f1中的n这个局部变量,当f1执行完毕后,垃圾回收机制发现n变量还在被result中引用所以垃圾回收机制不会把n回收释放。
      以至于n一直保存在result作用域链中。result的作用域链正常能访问f1中的局部变量n,形成闭包。

    3. nAdd():nAdd没有写var所以nAdd是全局变量,在调用nAdd()和result()是一样的都会形成闭包,匿名函数function(){n+=1}的作用域链中有n这个局部变量,所以当nAdd=funtion(){n+=1}时,这个匿名函数的作用域链保存到了全局变量nAdd形成闭包,调用nAdd()作用域链中找到f1局部变量n=999,n+1=1000。

    4. result() (le rôle de f2 La chaîne de domaines est enregistrée dans la variable globale de résultat)

    result() : Appelez result(), qui forme une fermeture : A le droit d'accéder aux variables dans une autre portée de fonction

    < br> É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.
    Pour 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 #🎜🎜##🎜🎜#

    répondre
    0
  • PHP中文网

    PHP中文网2017-05-18 10:52:47

    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.

    répondre
    0
  • Annulerrépondre