Une explication simple des fermetures en JS
Tout le monde a entendu parler des fermetures dans JS. Cet article présente les fermetures dans JS à travers un exemple de code. Il a une valeur de référence. Les amis intéressés devraient y jeter un œil.
1. "La fermeture consiste à accéder aux variables dans toutes les étendues."
[Exemple 1]
var name = 'wangxi' function user () { // var name = 'wangxi' function getName () { console.log(name) } getName() } user() // wangxi
Pour obtenir le nom dans la fonction getName, d'abord dans getName. function Recherchez le nom dans la portée, mais il n'est pas trouvé Ensuite, nous recherchons dans la portée de la fonction utilisateur, mais il n'est pas non plus trouvé. Nous continuons à remonter et trouvons que le nom existe dans la portée globale, donc nous. obtenez la valeur du nom et imprimez-la. C'est facile à comprendre ici, c'est-à-dire que les variables existent toutes dans la portée spécifiée. Si la variable souhaitée ne peut pas être trouvée dans la portée actuelle, la recherche se poursuivra dans la portée parent via la chaîne de portée jusqu'à la première avec la même. le nom est trouvé (ou s'il ne peut pas être trouvé, une ReferenceError sera levée). C'est le concept de chaîne de portées en js, c'est-à-dire que la portée enfant peut accéder aux variables de la portée parent en fonction de la chaîne de portées. Et si, au contraire, la portée parent voulait accéder aux variables de la portée enfant ? ——Cela doit être réalisé par la clôture.
[Exemple 2]
function user () { var name = 'wangxi' return function getName () { return name } } var userName = user()() console.log(userName) // wangxi
En analysant le code, nous savons que name est une variable locale qui existe dans la portée de la fonction utilisateur. Dans des circonstances normales, elle se trouve dans la portée externe. (voici le global) La variable name n'est pas accessible, mais par fermeture (renvoyant une fonction contenant la variable, voici la fonction getName), les variables sont accessibles à travers les portées (accès externe à interne). Par conséquent, l'instruction ci-dessus doit être complètement comprise comme :
La fermeture consiste à accéder aux variables à travers les portées - la portée interne peut conserver une référence aux variables dans la portée externe afin que (plus) la portée externe puisse accéder aux variables dans la portée intérieure. (Si vous ne comprenez toujours pas, lisez l'analyse suivante)
2. "Clôture : le papa est exécuté dans l'environnement du grand-père, et le petit-fils est rendu dans le père. A l'origine, le père a été exécuté, et l'environnement du père doit être effacé, mais le petit-fils a fait référence à l'environnement du père, donc le père n'a pas pu le libérer. En termes simples, une fermeture est un objet qui fait référence à l'environnement parent et le renvoie à un environnement de niveau supérieur. "
Comment comprenez-vous cela ? Regardez d'abord le code ci-dessous :
[Exemple 3]
function user () { var name = 'wangxi' return name } var userName = user() console.log(userName) // wangxi
Q : Est-ce une fermeture ?
R : Bien sûr que non. Tout d’abord, vous devez comprendre ce qu’est une fermeture. Bien qu'il semble que le nom de la variable locale dans la fonction utilisateur soit accessible dans la portée globale, le problème est qu'après l'exécution de l'utilisateur, le nom est également détruit, c'est-à-dire que le cycle de vie de la variable locale dans la fonction n'existe que pendant le cycle de déclaration de la fonction, la fonction est détruite et les variables à l'intérieur de la fonction sont automatiquement détruites.
Mais utiliser les fermetures est le contraire. Une fois la fonction exécutée, le cycle de vie se termine, mais les variables de la portée externe référencées par la fermeture existent toujours et existeront toujours jusqu'à ce que la portée qui exécute la fermeture soit terminée. Détruisez, les variables locales ici seront détruites (si la fermeture est référencée dans l'environnement global, la portée référencée par la fermeture ne sera détruite que lorsque l'environnement global sera détruit, comme le programme se termine, le navigateur est fermé, etc. ). Par conséquent, afin d’éviter les pertes de mémoire causées par les fermetures, il est recommandé de détruire manuellement les fermetures après utilisation. Toujours le même que l'exemple 2 ci-dessus, légèrement modifié :
[Exemple 4]
function user () { var name = 'wangxi' return function getName () { return name } } var userName = user()() // userName 变量中始终保持着对 name 的引用 console.log(userName) // wangxi userName = null // 销毁闭包,释放内存
[Pourquoi user()() a deux crochets : l'exécution de user() renvoie la fonction getName, dans afin d'obtenir la variable name, vous devez exécuter une fois la fonction getName renvoyée, c'est donc user()()】
Selon le point 2, analysez le code : la variable userName est créée dans la portée globale (grand-père ), enregistre la référence au résultat final de retour de la fonction utilisateur (c'est-à-dire la valeur du nom de la variable locale), exécute user()() (père) et renvoie le nom (petit-fils). après avoir exécuté user()() Après cela, l'environnement de l'utilisateur (père) doit être effacé, mais comme le nom du résultat renvoyé (petit-fils) fait référence à l'environnement du père (car le nom existe à l'origine dans la portée de l'utilisateur), l'environnement de l'utilisateur ne peut pas être libéré (cela entraînera une perte de mémoire).
Donc ["Une fermeture est un objet qui fait référence à l'environnement parent et renvoie un objet de l'environnement parent vers un environnement de niveau supérieur."] Comment comprendre ?
Disons les choses autrement : si une fonction fait référence à un objet dans l'environnement parent et renvoie l'objet à l'environnement de niveau supérieur dans cette fonction, alors cette fonction est une fermeture.
Regardez l'exemple ci-dessus :
La fonction getName fait référence à l'objet (nom de la variable) dans l'environnement utilisateur (parent) et renvoie la variable de nom à l'environnement global (niveau supérieur) dans l'environnement de la fonction), getName est donc une fermeture.
3. "Les fonctions en JavaScript s'exécutent dans la portée dans laquelle elles sont définies, et non dans la portée dans laquelle elles sont exécutées."
Cette phrase explique l'utilisation des variables dans les fermetures. est utile. Regardons l'exemple suivant :
var name = 'Schopenhauer' function getName () { console.log(name) } function myName () { var name = 'wangxi' getName() } myName() // Schopenhauer
Si le résultat de l'exécution de myName() est différent de ce que vous imaginiez, vous devez revenir en arrière et lire la phrase ci-dessus,
Fonctions en JavaScript, exécutés dans la portée dans laquelle ils sont définis, et non dans la portée dans laquelle ils sont exécutés
执行 myName,函数内部执行了 getName,而 getName 是在全局环境下定义的,因此尽管在 myName 中定义了变量 name,对getName 的执行并无影响,getName 中打印的依然是全局作用域下的 name。
我们稍微改一下代码:
var name = 'Schopenhauer' function getName () { var name = 'Aristotle' var intro = function() { // 这是一个闭包 console.log('I am ' + name) } return intro } function showMyName () { var name = 'wangxi' var myName = getName() myName() } showMyName() // I am Aristotle
结果和你想象的一样吗?结果留作聪明的你自己分析~
以上就是对 js 中闭包的理解,如果有误,欢迎指正。最后引用一段知乎问题下关于闭包概念的一个回答。
什么是闭包?
简单来说,闭包是指可以访问另一个函数作用域变量的函数,一般是定义在外层函数中的内层函数。
为什么需要闭包?
局部变量无法共享和长久的保存,而全局变量可能造成变量污染,所以我们希望有一种机制既可以长久的保存变量又不会造成全局污染。
特点
占用更多内存
不容易被释放
何时使用?
变量既想反复使用,又想避免全局污染
如何使用?
定义外层函数,封装被保护的局部变量。
定义内层函数,执行对外部函数变量的操作。
外层函数返回内层函数的对象,并且外层函数被调用,结果保存在一个全局的变量中。
相关推荐:
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!

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)

Sujets chauds

Le numéro de série du disque dur est un identifiant important du disque dur et est généralement utilisé pour identifier de manière unique le disque dur et identifier le matériel. Dans certains cas, nous pouvons avoir besoin d'interroger le numéro de série du disque dur, par exemple lors de l'installation d'un système d'exploitation, de la recherche du pilote de périphérique approprié ou de la réparation du disque dur. Cet article présentera quelques méthodes simples pour vous aider à vérifier le numéro de série du disque dur. Méthode 1 : utilisez l’invite de commande Windows pour ouvrir l’invite de commande. Dans le système Windows, appuyez sur les touches Win+R, entrez « cmd » et appuyez sur la touche Entrée pour ouvrir la commande

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de reconnaissance vocale en ligne Introduction : Avec le développement continu de la technologie, la technologie de reconnaissance vocale est devenue une partie importante du domaine de l'intelligence artificielle. Le système de reconnaissance vocale en ligne basé sur WebSocket et JavaScript présente les caractéristiques d'une faible latence, d'un temps réel et d'une multiplateforme, et est devenu une solution largement utilisée. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de reconnaissance vocale en ligne.

Nous voyons souvent l'introduction du nombre d'écrans K dont nous disposons lors de l'achat de téléviseurs, d'ordinateurs ou de téléphones portables, comme les écrans 2,8K. À cette époque, il y aura des amis qui ne connaissent pas grand-chose aux appareils électroniques et seront curieux de savoir ce que signifie cet écran 2,8K et quelle est la résolution. Que signifie un écran 2,8k ? Réponse : Un écran 2,8k signifie que la résolution de l'écran est de 2880*18002K, ce qui signifie que le nombre de pixels horizontaux est supérieur à 2000. Pour un écran de même taille, plus la résolution est élevée, meilleure est la qualité de l'image. . Introduction à la résolution 1. Étant donné que les points, lignes et surfaces sur l'écran sont tous composés de pixels, plus le moniteur peut afficher de pixels, plus l'image est fine et plus d'informations peuvent être affichées dans la même zone d'écran. 2. Plus la résolution est élevée, plus le nombre de pixels est élevé et plus l'image détectée est nette.

WebSocket et JavaScript : technologies clés pour réaliser des systèmes de surveillance en temps réel Introduction : Avec le développement rapide de la technologie Internet, les systèmes de surveillance en temps réel ont été largement utilisés dans divers domaines. L'une des technologies clés pour réaliser une surveillance en temps réel est la combinaison de WebSocket et de JavaScript. Cet article présentera l'application de WebSocket et JavaScript dans les systèmes de surveillance en temps réel, donnera des exemples de code et expliquera leurs principes de mise en œuvre en détail. 1. Technologie WebSocket

Introduction à l'utilisation de JavaScript et de WebSocket pour mettre en œuvre un système de commande en ligne en temps réel : avec la popularité d'Internet et les progrès de la technologie, de plus en plus de restaurants ont commencé à proposer des services de commande en ligne. Afin de mettre en œuvre un système de commande en ligne en temps réel, nous pouvons utiliser les technologies JavaScript et WebSocket. WebSocket est un protocole de communication full-duplex basé sur le protocole TCP, qui peut réaliser une communication bidirectionnelle en temps réel entre le client et le serveur. Dans le système de commande en ligne en temps réel, lorsque l'utilisateur sélectionne des plats et passe une commande

Comment utiliser WebSocket et JavaScript pour mettre en œuvre un système de réservation en ligne. À l'ère numérique d'aujourd'hui, de plus en plus d'entreprises et de services doivent fournir des fonctions de réservation en ligne. Il est crucial de mettre en place un système de réservation en ligne efficace et en temps réel. Cet article explique comment utiliser WebSocket et JavaScript pour implémenter un système de réservation en ligne et fournit des exemples de code spécifiques. 1. Qu'est-ce que WebSocket ? WebSocket est une méthode full-duplex sur une seule connexion TCP.

JavaScript et WebSocket : Construire un système efficace de prévisions météorologiques en temps réel Introduction : Aujourd'hui, la précision des prévisions météorologiques revêt une grande importance pour la vie quotidienne et la prise de décision. À mesure que la technologie évolue, nous pouvons fournir des prévisions météorologiques plus précises et plus fiables en obtenant des données météorologiques en temps réel. Dans cet article, nous apprendrons comment utiliser la technologie JavaScript et WebSocket pour créer un système efficace de prévisions météorologiques en temps réel. Cet article démontrera le processus de mise en œuvre à travers des exemples de code spécifiques. Nous

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest
