J'essaie de mon mieux pour envelopper ma tête autour de la fermeture JavaScript.
J'obtiens qu'en retournant une fonction interne, il aura accès à n'importe quelle variable définie dans son parent immédiat.
Où cela me serait-il utile? Peut-être que je n'ai pas encore tout à fait compris. La plupart des exemples que j'ai vus en ligne ne fournissent aucun code du monde réel, juste de vagues exemples.
Quelqu'un peut-il me montrer une utilisation réelle d'une fermeture?
Est-ce celui-ci, par exemple?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + '\nYou have been warned ' + calledCount + ' times.');
};
};
var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();
Réponses:
J'ai utilisé des fermetures pour faire des choses comme:
Comme vous pouvez le voir,
a
est maintenant un objet, avec une méthodepublicfunction
(a.publicfunction()
) qui appelleprivatefunction
, qui n'existe qu'à l'intérieur de la fermeture. Vous ne pouvez PAS appelerprivatefunction
directement (iea.privatefunction()
), justepublicfunction()
.C'est un exemple minimal mais peut-être pouvez-vous en voir les utilisations? Nous l'avons utilisé pour appliquer des méthodes publiques / privées.
la source
Supposons que vous souhaitiez compter le nombre de fois où l'utilisateur a cliqué sur un bouton d'une page Web.
Pour cela, vous déclenchez une fonction sur
onclick
événement de bouton pour mettre à jour le décompte de la variableMaintenant, il pourrait y avoir de nombreuses approches comme:
1) Vous pouvez utiliser une variable globale et une fonction pour augmenter le compteur :
Mais, l'écueil est que tout script sur la page peut changer le compteur, sans appeler
updateClickCount()
.2) Maintenant, vous pourriez penser à déclarer la variable à l'intérieur de la fonction:
Mais salut! Chaque fois que la
updateClickCount()
fonction est appelée, le compteur est remis à 1.3) Penser aux fonctions imbriquées ?
Les fonctions imbriquées ont accès à l'étendue "au-dessus" d'elles.
Dans cet exemple, la fonction interne
updateClickCount()
a accès à la variable compteur dans la fonction parentcountWrapper()
Cela aurait pu résoudre le contre-dilemme, si vous pouviez accéder à la
updateClickCount()
fonction de l'extérieur et que vous deviez également trouver un moyen de l'exécutercounter = 0
une seule fois pas à chaque fois.4) Fermeture à la rescousse! (fonction auto-invoquante) :
La fonction auto-invoquante ne s'exécute qu'une seule fois. Il met
counter
à zéro (0) et renvoie une expression de fonction.Cette façon
updateClickCount
devient une fonction. La partie "merveilleuse" est qu'elle peut accéder au compteur dans la portée parent.C'est ce qu'on appelle une fermeture JavaScript . Il permet à une fonction d'avoir des variables " privées ".
Le
counter
est protégé par l'étendue de la fonction anonyme et ne peut être modifié qu'à l'aide de la fonction add!Exemple plus vivant sur la fermeture:
Référence: https://www.w3schools.com/js/js_function_closures.asp
la source
L'exemple que vous donnez est excellent. Les fermetures sont un mécanisme d'abstraction qui vous permet de séparer les problèmes très proprement. Votre exemple est un cas de séparation de l'instrumentation (comptage des appels) de la sémantique (une API de rapport d'erreurs). D'autres utilisations incluent:
Passer un comportement paramétré dans un algorithme (programmation classique d'ordre supérieur):
Simuler une programmation orientée objet:
Implémentation d'un contrôle de flux exotique, tel que la gestion des événements de jQuery et les API AJAX.
la source
int
?) La dernière fois que j'ai vérifié, JavaScript était un langage de type canard. Vous pensiez peut-être à Java?Je sais que je suis super en retard pour répondre à cette question, mais cela pourrait aider quiconque cherche toujours la réponse en 2018.
Fermetures Javascript peuvent être utilisés pour mettre en œuvre des gaz et debounce fonctionnalité dans votre application.
Limitation :
La limitation limite le nombre maximal de fois qu'une fonction peut être appelée dans le temps. Comme dans «exécuter cette fonction au plus une fois toutes les 100 millisecondes».
Code:
Anti - rebond :
Le rebouncing limite une fonction à ne plus être appelée tant qu'un certain laps de temps ne s'est pas écoulé sans qu'elle soit appelée. Comme dans "n'exécuter cette fonction que si 100 millisecondes se sont écoulées sans qu'elle soit appelée".
Code:
Comme vous pouvez le voir, les fermetures ont aidé à implémenter deux belles fonctionnalités que chaque application Web devrait avoir pour offrir une fonctionnalité d'interface utilisateur fluide.
J'espère que cela aidera quelqu'un.
la source
Oui, c'est un bon exemple de fermeture utile. L'appel à warnUser crée la
calledCount
variable dans sa portée et renvoie une fonction anonyme qui est stockée dans lawarnForTamper
variable. Parce qu'il y a toujours une fermeture utilisant la variable appeléeCompte, elle n'est pas supprimée à la sortie de la fonction, donc chaque appel à lawarnForTamper()
va augmenter la variable de portée et alerter la valeur.Le problème le plus courant que je vois sur StackOverflow est celui où quelqu'un veut "retarder" l'utilisation d'une variable qui est augmentée à chaque boucle, mais parce que la variable est limitée, chaque référence à la variable se ferait après la fin de la boucle, entraînant la état final de la variable:
Cela entraînerait que chaque alerte affiche la même valeur de
i
, la valeur à laquelle elle a été augmentée à la fin de la boucle. La solution consiste à créer une nouvelle fermeture, une portée distincte pour la variable. Cela peut être fait en utilisant une fonction anonyme exécutée instantanément, qui reçoit la variable et stocke son état comme argument:la source
Dans le langage JavaScript (ou n'importe quel ECMAScript), en particulier, les fermetures sont utiles pour masquer l'implémentation des fonctionnalités tout en révélant l'interface.
Par exemple, imaginez que vous écrivez une classe de méthodes utilitaires de date et que vous souhaitez autoriser les utilisateurs à rechercher des noms de semaine par index, mais que vous ne voulez pas qu'ils puissent modifier le tableau de noms que vous utilisez sous le capot.
Notez que le
days
tableau pourrait simplement être stocké en tant que propriété de l'dateUtil
objet, mais il serait alors visible pour les utilisateurs du script et ils pourraient même le modifier s'ils le voulaient, sans même avoir besoin de votre code source. Cependant, comme il est entouré par la fonction anonyme qui renvoie la fonction de recherche de date, il n'est accessible que par la fonction de recherche, il est donc désormais inviolable.la source
Il y a une section sur les fermetures pratiques sur le Mozilla Developer Network .
la source
return function ()...
le code fonctionne toujours bien. La fermeture n'est pas nécessaireUne autre utilisation courante des fermetures consiste à lier
this
une méthode à un objet spécifique, ce qui permet de l'appeler ailleurs (comme un gestionnaire d'événements).Chaque fois qu'un événement mousemove se déclenche,
watcher.follow(evt)
est appelé.Les fermetures sont également une partie essentielle des fonctions d'ordre supérieur, permettant le modèle très courant de réécriture de plusieurs fonctions similaires en une seule fonction d'ordre supérieur en paramétrant les parties dissemblables. À titre d'exemple abstrait,
devient
où A et B ne sont pas des unités syntaxiques mais des chaînes de code source (pas des littéraux de chaîne).
Voir " Rationaliser mon javascript avec une fonction " pour un exemple concret.
la source
Ici, j'ai une salutation que je veux dire plusieurs fois. Si je crée une fermeture, je peux simplement appeler cette fonction pour enregistrer le message d'accueil. Si je ne crée pas la fermeture, je dois passer mon nom à chaque fois.
Sans fermeture ( https://jsfiddle.net/lukeschlangen/pw61qrow/3/ ):
Avec une fermeture ( https://jsfiddle.net/lukeschlangen/Lb5cfve9/3/ ):
la source
Si vous êtes à l'aise avec le concept d'instanciation d'une classe dans le sens orienté objet (c'est-à-dire pour créer un objet de cette classe), vous êtes sur le point de comprendre les fermetures.
Pensez-y de cette façon: lorsque vous instanciez deux objets Personne, vous savez que la variable de membre de classe "Nom" n'est pas partagée entre les instances; chaque objet a sa propre «copie». De même, lorsque vous créez une fermeture, la variable libre («appeléCompte» dans votre exemple ci-dessus) est liée à «l'instance» de la fonction.
Je pense que votre saut conceptuel est légèrement entravé par le fait que chaque fonction / fermeture renvoyée par la fonction warnUser (à part: c'est une fonction d'ordre supérieur ) la fermeture lie 'appeléCompte' avec la même valeur initiale (0), alors que souvent lors de la création de fermetures il est plus utile de passer différents initialiseurs dans la fonction d'ordre supérieur, un peu comme passer des valeurs différentes au constructeur d'une classe.
Donc, supposez que lorsque 'calledCount' atteint une certaine valeur, vous souhaitez mettre fin à la session de l'utilisateur; vous pouvez vouloir des valeurs différentes pour cela selon que la demande provient du réseau local ou du grand mauvais Internet (oui, c'est un exemple artificiel). Pour ce faire, vous pouvez passer différentes valeurs initiales pour appeléCompte dans warnUser (c'est-à-dire -3 ou 0?).
Une partie du problème avec la littérature est la nomenclature utilisée pour les décrire ("portée lexicale", "variables libres"). Ne vous y trompez pas, les fermetures sont plus simples qu'il n'y paraît ... prima facie ;-)
la source
Ici, j'ai un exemple simple de concept de fermeture que nous pouvons utiliser dans notre site de commerce électronique ou bien d'autres. J'ajoute mon lien jsfiddle avec l'exemple. il contient une petite liste de produits de 3 articles et un compteur de panier.
Jsfiddle
la source
Utilisation des fermetures:
Les fermetures sont l'une des fonctionnalités les plus puissantes de JavaScript. JavaScript permet l'imbrication des fonctions et accorde à la fonction interne un accès complet à toutes les variables et fonctions définies à l'intérieur de la fonction externe (et à toutes les autres variables et fonctions auxquelles la fonction externe a accès). Cependant, la fonction externe n'a pas accès aux variables et fonctions définies à l'intérieur de la fonction interne. Cela fournit une sorte de sécurité pour les variables de la fonction interne. De plus, puisque la fonction interne a accès à la portée de la fonction externe, les variables et les fonctions définies dans la fonction externe vivront plus longtemps que la fonction externe elle-même, si la fonction interne parvient à survivre au-delà de la durée de vie de la fonction externe.
Exemple :
Dans le code ci-dessus, la variable de nom de la fonction externe est accessible aux fonctions internes, et il n'y a pas d'autre moyen d'accéder aux variables internes sauf via les fonctions internes. Les variables internes de la fonction interne agissent comme des magasins sûrs pour les fonctions internes. Ils contiennent des données "persistantes", mais sécurisées, avec lesquelles les fonctions internes peuvent fonctionner. Les fonctions n'ont même pas besoin d'être attribuées à une variable ou d'avoir un nom. lire ici pour plus de détails
la source
J'aime l' exemple de l' usine de fonctions de Mozilla .
la source
Le modèle de module JavaScript utilise des fermetures. Son joli motif vous permet d'avoir quelque chose comme des vars "publics" et "privés".
la source
J'ai écrit un article il y a quelque temps sur la façon dont les fermetures peuvent être utilisées pour simplifier le code de gestion des événements. Il compare la gestion des événements ASP.NET à jQuery côté client.
http://www.hackification.com/2009/02/20/closures-simplify-event-handling-code/
la source
Ce fil m'a énormément aidé à mieux comprendre le fonctionnement des fermetures. Depuis, j'ai fait mes propres expériences et j'ai trouvé ce code assez simple qui peut aider d'autres personnes à voir comment les fermetures peuvent être utilisées de manière pratique et comment utiliser la fermeture à différents niveaux pour maintenir des variables similaires à statiques et / ou des variables globales sans risque de les écraser ou de les confondre avec des variables globales. Cela permet de garder une trace des clics sur les boutons, à la fois au niveau local pour chaque bouton individuel et au niveau global, en comptant chaque clic sur le bouton, contribuant à un chiffre unique. Remarque Je n'ai utilisé aucune variable globale pour ce faire, ce qui est en quelque sorte le point de l'exercice - avoir un gestionnaire qui peut être appliqué à n'importe quel bouton qui contribue également à quelque chose à l'échelle mondiale.
S'il vous plaît, experts, faites-moi savoir si j'ai commis des mauvaises pratiques ici! J'apprends toujours ce truc moi-même.
la source
Référence: Utilisation pratique des fermetures
Dans la pratique, les fermetures peuvent créer des conceptions élégantes, permettant la personnalisation de divers calculs, appels différés, rappels, création d'une portée encapsulée, etc.
Un exemple de la méthode de tri des tableaux qui accepte comme argument la fonction condition de tri:
Mappage des fonctionnelles comme méthode de mappage des tableaux qui mappe un nouveau tableau par la condition de l'argument fonctionnel:
Il est souvent pratique d'implémenter des fonctions de recherche en utilisant des arguments fonctionnels définissant des conditions de recherche presque illimitées:
Nous pouvons également noter l'application de fonctionnelles comme, par exemple, une méthode forEach qui applique une fonction à un tableau d'éléments:
Une fonction est appliquée aux arguments (à une liste d'arguments - en application et aux arguments positionnés - en appel):
Appels différés:
Fonctions de rappel:
Création d'une portée encapsulée dans le but de masquer des objets auxiliaires:
la source
Violon
la source
Les fermetures sont un moyen utile de créer générateurs, une séquence incrémentée à la demande:
Les différences sont résumées comme suit:
Références
la source
Dans l'échantillon donné, la valeur de la variable incluse «compteur» est protégée et ne peut être modifiée qu'en utilisant les fonctions données (incrémenter, décrémenter). parce que c'est dans une fermeture,
la source
Expliquer l'utilisation pratique d'une fermeture en JavaScript ---
Lorsque nous créons une fonction à l'intérieur d'une autre fonction, nous créons une fermeture. Les fermetures sont puissantes car elles sont capables de lire et de manipuler les données de ses fonctions externes. Chaque fois qu'une fonction est invoquée, une nouvelle étendue est créée pour cet appel. La variable locale déclarée à l'intérieur de la fonction appartient à cette portée et n'est accessible qu'à partir de cette fonction. Lorsque la fonction a terminé l'exécution, la portée est généralement détruite.
Un exemple simple d'une telle fonction est le suivant:
Dans l'exemple ci-dessus, la fonction buildName () déclare un message d'accueil de variable locale et le renvoie. Chaque appel de fonction crée une nouvelle portée avec une nouvelle variable locale. Une fois la fonction exécutée, nous n'avons plus aucun moyen de faire à nouveau référence à cette étendue, c'est donc une récupération de place.
Mais qu'en est-il lorsque nous avons un lien avec cette portée?
Regardons la fonction suivante:
La fonction sayName () de cet exemple est une fermeture. La fonction sayName () a sa propre portée locale (avec la variable welcome) et a également accès à la portée de la fonction externe (englobante). Dans ce cas, la variable salutation de buildName ().
Une fois l'exécution de buildName terminée, la portée n'est pas détruite dans ce cas. La fonction sayMyName () y a toujours accès, elle ne sera donc pas récupérée. Cependant, il n'y a pas d'autre moyen d'accéder aux données depuis le périmètre externe, sauf la fermeture. La fermeture sert de passerelle entre le contexte mondial et la portée extérieure.
la source
J'essaie d'apprendre les clousures et je pense que l'exemple que j'ai créé est un cas d'utilisation pratique. Vous pouvez exécuter l'extrait de code et voir le résultat dans la console. nous avons deux utilisateurs distincts qui ont des données distinctes. Chacun d'eux peut voir l'état réel et le mettre à jour.
la source