


Comprendre et utiliser le mécanisme de fermeture de JavaScript_Connaissances de base
Le grand camarade Einstein a dit un jour : "Si vous ne pouvez pas expliquer clairement quelque chose à un enfant de 6 ans, alors vous ne le comprenez pas vous-même." Cependant, lorsque j’ai expliqué ce qu’étaient les fermetures à un ami de 27 ans, j’ai complètement échoué.
Il s'agissait à l'origine d'une question soulevée par un ami étranger sur Stack Overflow à propos des fermetures JavaScript. Cependant, puisque cette question a été posée sur Stack Overflow, bien sûr de nombreux experts viendront y répondre. Certaines réponses sont effectivement des classiques, comme la suivante :
.Si vous définissez une fonction interne dans une fonction externe, c'est-à-dire une fonction imbriquée, alors la fonction interne peut également accéder aux variables de la fonction externe :
function foo(x) { var tmp = 3; function bar(y) { alert(x + y + (++tmp)); } bar(10); } foo(2); // alert 16 foo(2); // alert 16 foo(2); // alert 16
Ce code peut être exécuté correctement et renvoie le résultat : 16, car bar peut accéder à la variable tmp de la fonction externe et peut également accéder au paramètre x de la fonction externe foo. Mais l’exemple ci-dessus n’est pas une clôture !
Pour implémenter la fermeture, la fonction interne doit être renvoyée comme valeur de retour de la fonction externe. Avant de revenir, la fonction interne verrouillera toutes les variables de la fonction externe qui ont été accédées dans la mémoire. ces variables Il résidera dans la mémoire du bar et ne sera pas recyclé par le garbage collector, comme suit :
function foo(x) { var tmp = 3; return function (y) { alert(x + y + (++tmp)); } } var bar = foo(2); // bar 现在是个闭包了 bar(10); // alert 16 bar(10); // alert 17 bar(10); // alert 18
Dans le code ci-dessus, lorsque bar est exécuté pour la première fois, le résultat sera toujours renvoyé : 16, car bar peut toujours accéder à x et tmp, bien qu'il n'existe plus directement dans la portée de foo. Ainsi, puisque tmp est verrouillé lors de la fermeture de bar, tmp sera incrémenté à chaque fois que bar est exécuté, donc lorsque bar est exécuté pour la deuxième et la troisième fois, 17 et 18 sont renvoyés respectivement.
Dans cet exemple, x est juste une valeur pure Lorsque foo est appelé, la valeur x sera copiée dans foo en tant que paramètre.
Mais lorsque JavaScript gère des objets, il utilise toujours des références. Si vous appelez foo avec un objet comme paramètre, alors ce qui est passé dans foo est en fait une référence à l'objet d'origine, donc l'objet d'origine équivaut également à être fermé. . , comme suit :
function foo(x) { var tmp = 3; return function (y) { alert(x + y + tmp++); x.memb = x.memb ? x.memb + 1 : 1; alert(x.memb); } } var age = new Number(2); var bar = foo(age); // bar 现在是个闭包了 bar(10); // alert 15 1 bar(10); // alert 16 2 bar(10); // alert 17 3
Comme prévu, chaque fois que bar(10) est exécuté, non seulement tmp est incrémenté, mais x.memb est également incrémenté, car x dans le corps de la fonction et age en dehors de la fonction font référence au même objet.
via http://stackoverflow.com/questions/111102/how-do-javascript-closures-work
Supplément : Grâce aux exemples ci-dessus, vous devriez être en mesure de comprendre plus clairement les fermetures. Si vous pensez l'avoir compris, vous pouvez tenter de deviner le résultat de l'exécution du code suivant :
function foo(x) { var tmp = 3; return function (y) { alert(x + y + tmp++); x.memb = x.memb ? x.memb + 1 : 1; alert(x.memb); } } var age = new Number(2); var bar1 = foo(age); // bar1 现在是个闭包了 bar1(10); // alert 15 1 bar1(10); // alert 16 2 bar1(10); // alert 17 3 var bar2 = foo(age); // bar2 现在也是个闭包了 bar2(10); // alert ? ? bar2(10); // alert ? ? bar2(10); // alert ? ? bar1(10); // alert ? ? bar1(10); // alert ? ? bar1(10); // alert ? ?
Lorsqu'elles sont utilisées dans la pratique, les fermetures peuvent créer des designs très élégants, permettant de personnaliser les différentes méthodes de calcul définies sur funarg. Voici un exemple de tri par tableau, qui accepte une fonction de condition de tri comme paramètre :
[1, 2, 3].sort(function (a, b) { ... // 排序条件 });
Le même exemple est que la méthode map d'un tableau mappe le tableau d'origine à un nouveau tableau en fonction des conditions définies dans la fonction :
[1, 2, 3].map(function (element) { return element * 2; }); // [2, 4, 6]
À l'aide de paramètres fonctionnels, vous pouvez facilement implémenter une méthode de recherche et prendre en charge des conditions de recherche illimitées :
someCollection.find(function (element) { return element.someProperty == 'searchCondition'; });
Il existe également des fonctions d'application, telles que la méthode commune forEach, qui applique la fonction à chaque élément du tableau :
[1, 2, 3].forEach(function (element) { if (element % 2 != 0) { alert(element); } }); // 1, 3
À propos, les méthodes apply et call des objets fonction peuvent également être utilisées comme fonctions d'application dans la programmation fonctionnelle. Ici, nous les considérons comme des fonctions d'application - des fonctions appliquées aux paramètres (dans apply c'est la liste des paramètres, dans call c'est un paramètre indépendant) :
(function () { alert([].join.call(arguments, ';')); // 1;2;3 }).apply(this, [1, 2, 3]);
Les fermetures ont une autre application très importante : les appels différés :
var a = 10; setTimeout(function () { alert(a); // 10, after one second }, 1000); 还有回调函数: //... var x = 10; // only for example xmlHttpRequestObject.onreadystatechange = function () { // 当数据就绪的时候,才会调用; // 这里,不论是在哪个上下文中创建 // 此时变量“x”的值已经存在了 alert(x); // 10 }; //...
Vous pouvez également créer des étendues d'encapsulation pour masquer les objets d'assistance :
var foo = {}; // 初始化 (function (object) { var x = 10; object.getX = function _getX() { return x; }; })(foo); alert(foo.getX()); // 获得闭包 "x" – 10

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

En C++, une fermeture est une expression lambda qui peut accéder à des variables externes. Pour créer une fermeture, capturez la variable externe dans l'expression lambda. Les fermetures offrent des avantages tels que la réutilisabilité, la dissimulation des informations et une évaluation paresseuse. Ils sont utiles dans des situations réelles telles que les gestionnaires d'événements, où la fermeture peut toujours accéder aux variables externes même si elles sont détruites.

Les expressions C++ Lambda prennent en charge les fermetures, qui enregistrent les variables de portée de fonction et les rendent accessibles aux fonctions. La syntaxe est [capture-list](parameters)->return-type{function-body}. capture-list définit les variables à capturer. Vous pouvez utiliser [=] pour capturer toutes les variables locales par valeur, [&] pour capturer toutes les variables locales par référence, ou [variable1, variable2,...] pour capturer des variables spécifiques. Les expressions Lambda ne peuvent accéder qu'aux variables capturées mais ne peuvent pas modifier la valeur d'origine.

Une fermeture est une fonction imbriquée qui peut accéder aux variables dans la portée de la fonction externe. Ses avantages incluent l'encapsulation des données, la conservation de l'état et la flexibilité. Les inconvénients incluent la consommation de mémoire, l’impact sur les performances et la complexité du débogage. De plus, les fermetures peuvent créer des fonctions anonymes et les transmettre à d'autres fonctions sous forme de rappels ou d'arguments.

Titre : Fuites de mémoire causées par les fermetures et solutions Introduction : Les fermetures sont un concept très courant en JavaScript, qui permettent aux fonctions internes d'accéder aux variables des fonctions externes. Cependant, les fermetures peuvent provoquer des fuites de mémoire si elles ne sont pas utilisées correctement. Cet article explorera le problème de fuite de mémoire provoqué par les fermetures et fournira des solutions et des exemples de code spécifiques. 1. Fuites de mémoire causées par les fermetures La caractéristique des fermetures est que les fonctions internes peuvent accéder aux variables des fonctions externes, ce qui signifie que les variables référencées dans les fermetures ne seront pas récupérées. S'il est mal utilisé,

Les fermetures de fonctions du langage Go jouent un rôle essentiel dans les tests unitaires : Capture de valeurs : les fermetures peuvent accéder aux variables dans la portée externe, permettant ainsi de capturer et de réutiliser les paramètres de test dans des fonctions imbriquées. Simplifiez le code de test : en capturant les valeurs, les fermetures simplifient le code de test en éliminant le besoin de définir des paramètres à plusieurs reprises pour chaque boucle. Améliorez la lisibilité : utilisez des fermetures pour organiser la logique de test, rendant ainsi le code de test plus clair et plus facile à lire.

Oui, la simplicité et la lisibilité du code peuvent être optimisées grâce à des appels et des fermetures enchaînés : les appels en chaîne lient les appels de fonction dans une interface fluide. Les fermetures créent des blocs de code réutilisables et accèdent à des variables en dehors des fonctions.

L'impact des pointeurs de fonction et des fermetures sur les performances de Go est le suivant : Pointeurs de fonction : légèrement plus lents que les appels directs, mais améliorent la lisibilité et la réutilisabilité. Fermetures : généralement plus lentes, mais encapsulent les données et le comportement. Cas pratique : les pointeurs de fonction peuvent optimiser les algorithmes de tri et les fermetures peuvent créer des gestionnaires d'événements, mais ils entraîneront des pertes de performances.

Les fermetures en Java permettent aux fonctions internes d'accéder aux variables de portée externe même si la fonction externe est terminée. Implémentée via des classes internes anonymes, la classe interne contient une référence à la classe externe et maintient les variables externes actives. Les fermetures augmentent la flexibilité du code, mais vous devez être conscient du risque de fuite de mémoire, car les références à des variables externes par des classes internes anonymes maintiennent ces variables en vie.
