Maison  >  Article  >  interface Web  >  Qu'est-ce qu'une fermeture en javascript

Qu'est-ce qu'une fermeture en javascript

青灯夜游
青灯夜游original
2021-10-18 11:59:222224parcourir

En JavaScript, lorsque deux fonctions sont imbriquées l'une dans l'autre, la fonction interne est une fermeture. Une fermeture est une fonction qui a accès à des variables dans la portée d'une autre fonction. La manière la plus courante de créer une fermeture consiste à créer une autre fonction au sein d'une fonction et à accéder aux variables locales de cette fonction via l'autre fonction.

Qu'est-ce qu'une fermeture en javascript

L'environnement d'exploitation de ce tutoriel : système Windows 7, JavaScript version 1.8.5, ordinateur Dell G3.

1. Qu'est-ce qu'une fermeture ?

Une fermeture est une fonction qui peut lire les variables internes d'autres fonctions. En JavaScript, seules les sous-fonctions à l'intérieur d'une fonction peuvent lire les variables locales, les fermetures peuvent donc être comprises comme des « fonctions définies à l'intérieur d'une fonction ». Essentiellement, les fermetures constituent le pont entre l’intérieur d’une fonction et l’extérieur de la fonction. (L'application la plus typique des fermetures consiste à implémenter des fonctions de rappel).

2. Avantages, inconvénients et caractéristiques des fermetures en JS

Avantages :

1. Protéger la sécurité des variables au sein de la fonction

2. Conserver une variable en mémoire (elle changera si elle est utilisée trop) 3. Continuité logique Lorsque la fermeture est utilisée comme paramètre d'un autre appel de fonction, elle vous empêche de rompre avec la logique actuelle et d'écrire une logique supplémentaire séparément.

4. Variables locales qui facilitent le contexte d'appel.

5. Le renforcement de l'encapsulation peut assurer la protection des variables.

Inconvénients : 1. La mémoire résidente augmentera l'utilisation de la mémoire, et une utilisation inappropriée peut facilement provoquer des fuites de mémoire.

2. Il existe également un problème très grave, à savoir le problème du gaspillage de mémoire. Ce gaspillage de mémoire n'est pas seulement dû au fait qu'il réside en mémoire, mais plus important encore, une mauvaise utilisation des fermetures entraînera la génération de mémoire invalide.


Caractéristiques : 1. Fonctions imbriquées de fonctions

2. Les fonctions internes peuvent accéder aux variables des fonctions externes

3. Les paramètres et les variables ne seront pas recyclés.

3. Portée variable

Pour comprendre la fermeture, il ne suffit pas de comprendre uniquement le concept de fermeture ci-dessus. Tout d’abord, vous devez comprendre la portée variable spéciale de JavaScript.

1. Il n'y a que deux portées de variables : les variables globales et les variables locales.

2. La particularité du langage JavaScript est que les variables globales peuvent être lues directement à l'intérieur de la fonction, mais les variables locales à l'intérieur de la fonction ne peuvent pas être lues en dehors de la fonction.

3. Remarque : lorsque vous déclarez des variables dans une fonction, assurez-vous d'utiliser la commande var. Si vous ne l'utilisez pas, vous déclarez en fait une variable globale !

4. Interpréter les fermetures avec du code

Le processus de création de fermetures en Javascript est tel qu'illustré dans le programme suivant.

function a () {
   var i = 0;
   function b () {
      alert (i++);
   }
  return b;
}
var c = a();
c();  //函数调用

Caractéristiques du codeCe code a deux fonctionnalités :

1. La fonction b est imbriquée dans la fonction a

2. La fonction a renvoie la fonction b ;

De cette façon, après avoir exécuté var c = a(), la variable c pointe en fait vers la fonction b. Après avoir exécuté à nouveau c(), une fenêtre apparaîtra pour afficher la valeur de i (la première fois est 1). Ce code crée en fait une fermeture car la variable c en dehors de la fonction a fait référence à la fonction b à l'intérieur de la fonction a. En d’autres termes, lorsque la fonction b à l’intérieur de la fonction a est référencée par une variable extérieure à la fonction a, une fermeture est créée.

FonctionEn bref, la fonction de la fermeture est qu'après l'exécution et le retour de a, la fermeture empêche le mécanisme de récupération de place de Javascript de récupérer les ressources occupées par a, car la fonction interne b de a L'exécution de dépend des variables de a.

Dans l'exemple ci-dessus, en raison de l'existence d'une fermeture, i dans a existera toujours après le retour de la fonction a. De cette façon, chaque fois que c() est exécuté, i sera la valeur de i qui est alertée après l'ajout de 1. .

Alors imaginons une autre situation. Si a renvoie autre chose que la fonction b, la situation est complètement différente. Parce qu'après l'exécution de a, b n'est pas renvoyé au monde extérieur de a, mais est uniquement référencé par a. À ce stade, a ne sera référencé que par b. Par conséquent, les fonctions a et b se réfèrent l'une à l'autre mais ne sont pas perturbées. par le monde extérieur (référencé par le monde extérieur), les fonctions a et b seront recyclées.

Scénarios d'application1. Protégez les variables au sein de la fonction. Dans la fonction a, i n'est accessible que par la fonction b et n'est pas accessible par d'autres moyens, protégeant ainsi la sécurité de i.

2. Conserver une variable en mémoire. En raison de la fermeture, i dans la fonction a existe toujours en mémoire, donc chaque fois que c() est exécuté, i sera incrémenté de 1.

五、如何从外部读取函数内部的局部变量?

  出于种种原因,我们有时候需要获取到函数内部的局部变量。但是,上面(三、变量作用域)已经说过了,正常情况下,这是办不到的!只有通过变通的方法才能实现。那就是在函数内部,再定义一个函数。

function demo1 () {
    var n = 6699;
    function demo2 () {
      alert(n); // 6699
    }
  }

在上面的代码中,函数 demo2 就被包括在函数demo1内部,这时demo1内部的所有局部变量,对demo2都是可见的。但是反过来就不行,demo2内部的局部变量,对demo1就是不可见的。 

这就是Javascript语言特有的”链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。 

既然demo2可以读取demo1中的局部变量,那么只要把demo2作为返回值,我们不就可以在demo1外部读取它的内部变量了吗!

六、闭包的用途

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在demo1调用后被自动清除。 

那为什么会这样呢?原因就在于demo1是demo2的父函数,而demo2被赋给了一个全局变量,这导致demo2始终在内存中,而demo2的存在依赖于demo1,因此demo1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

七、使用闭包的注意点

1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 

2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

八、总结:

1、闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。 

2、不适合场景:返回闭包的函数是个非常大的函数。 

    闭包的典型框架应该就是jquery了。 

    闭包是javascript语言的一大特点,主要应用闭包场合主要是为了:设计私有的方法和变量。 

    这在做框架的时候体现更明显,有些方法和属性只是运算逻辑过程中的使用的,不想让外部修改这些属性,因此就可以设计一个闭包来只提供方法获取。 

3、 不必纠结到底怎样才算闭包,其实你写的每一个函数都算作闭包,即使是全局函数,你访问函数外部的全局变量时,就是闭包
的体现。

更多编程相关知识,请访问:编程入门!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn