Maison interface Web js tutoriel js学习之深入理解闭包

js学习之深入理解闭包

Dec 06, 2016 am 11:21 AM
js

闭包算是js里面比较不容易理解的点,尤其是对于没有编程基础的人来说。

其实闭包要注意的就那么几条,如果你都明白了那么征服它并不是什么难事儿。下面就让我们来谈一谈闭包的一些基本原理。

 闭包的概念

一个闭包就是一个函数和被创建的函数中的作用域对象的组合。(作用域对象下面会说)

通俗一点的就是 “ 只要一个函数中嵌套了一个或多个函数,那么我们就可以称它们构成了闭包。 ”

类似这样:

function A() {
 var i = 5;
 return function() {
  console.log('i = '+i);
 }
}
 
var a = A();
a(); // i = 5
Copier après la connexion

闭包的原理

1、外部函数的局部变量若会被闭包函数调用就不会在外部函数执行完毕之后立即被回收。

我们知道,不管什么语言,操作系统都会存在一个垃圾回收机制,将多余分配的空间回收掉以便减小内存。而一个函数的生命周期的是从调用它开始的,在函数调用完毕的时候函数内部的局部变量等都会被回收机制回收。

我们拿上述例子来说,当我们的外部函数A调用完毕时,A中的局部变量i按理说就会被操作系统回收而不存在,但是当我们用了闭包结果就不是那样了,i并不会被回收。试想,如果i被回收了那么返回的函数里面岂不是就是打印undefined了?

i为什么没有被回收?

在javascript执行一个函数的时候都会创建一个作用域对象,将函数中的局部变量(函数的形参也是局部变量)保存进去,伴随着那些传入函数的变量一起被初始化。

所以当调用A的时候就创建了一个作用域对象,我们姑且称之为Aa,那么这个Aa应该是这样的: Aa { i: 5; }; 在A函数返回一个函数之后,A执行完毕。Aa对象本应该被回收,但是由于返回的函数使用了Aa的属性i,所以返回的函数保存了一个指向Aa的引用,所以Aa不会被回收。

所以理解作用域对象,就能理解为什么函数的局部变量在遇到闭包的时候不会在函数调用完毕时立即被回收了。

再来个例子:

function A(age) {
 var name = 'wind';
 var sayHello = function() {
  console.log('hello, '+name+', you are '+age+' years old!');
 };
 return sayHello;
}
var wind = A(20);
wind(); // hello, wind, you are 20 years old!
Copier après la connexion

你能说出的它的作用域对象Ww是什么吗?

Ww{ age: 20; name: 'wind'; };

2、每调用一次外部函数就产生一个新的闭包,以前的闭包依旧存在且互不影响。

3、同一个闭包会保留上一次的状态,当它被再次调用时会在上一次的基础上进行。

每调用一次外部函数产生的作用域对象都不一样,你可以这样想,上面的例子,你每次传入的参数age不一样,所以就每次生成的对象不一样。

每调用一次外部函数那么就会生成一个新的作用域对象。

function A() {
 var num = 42;
 return function() { console.log(num++); }
}
var a = A();
a(); // 42
a(); // 43
 
var b = A(); // 重新调用A(),形成新闭包
b(); // 42
Copier après la connexion

这个代码让我们发现了两个事情,一、当我们连续调用两次a();,num会在原基础上自加。说明同一个闭包会保留上一次的状态,当它被再次调用时会在上一次的基础上进行。 二、我们的b();的结果为42,说明它是一个新的闭包,并且不受其他闭包的影响。

我们可以这样想,就好比我们吹肥皂泡一样,我每次吹一下(调用外部函数),就会产生一个新的肥皂泡(闭包),多个肥皂泡可以同时存在且两个肥皂泡之间不会相互影响。

4、在外部函数中存在的多个函数 “ 同生共死 ”

以下三个函数被同时声明并且都可以对作用域对象的属性(局部变量)进行访问与操作。

var fun1, fun2, fun3;
function A() {
 var num = 42;
 fun1 = function() { console.log(num); }
 fun2 = function() { num++; }
 fun3 = function() { num--; }
}
 
A();
fun1();  // 42
fun2();
fun2();
fun1();  // 44
fun3();
fun1();  //43
 
var old = fun1;
 
A();
fun1();  // 42
old();  // 43  上一个闭包的fun1()
Copier après la connexion

由于函数不能有多个返回值,所以我用了全局变量。我们再次可以看出在我们第二次调用A()时产生了一个新的闭包。

当闭包遇到循环变量

当我们说到闭包就不得不说当闭包遇到循环变量这一种情况,看如下代码:

function buildArr(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) {
    var item = &#39;item&#39; + i;
    result.push( function() {console.log(item + &#39; &#39; + arr[i])} );
  }
  return result;
}
 
var fnlist = buildArr([1,2,3]);
fnlist[0](); // item2 undefined
fnlist[1](); // item2 undefined
fnlist[2](); // item2 undefined
Copier après la connexion

怎么会这样呢?我们预想的三个输出应该是 item0 1, item1 2, item2 3。为什么结果却是返回的result数组里面存储了三个 item2 undefined ?

原来当闭包遇到循环变量时都是循环结束之后统一保存变量值,拿我们上面的例子来说,i是循环变量,当循环全部结束的时候i正好是i++之后的3,而arr[3]是没有值的,所以为undefined,有人会疑惑:为什么item的值是item2,难道不应该是item3吗?注意,在最后一次循环的时候也就是i = 2的时候,item的值为item2,当i++,i = 3循环条件不满足循环结束,此时的item的值已经定下来了,所以此时的arr[i]为arr[3],而item为item2。这样能理解吗?如果我们将代码改成这样那就说得通了:

function buildArr(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) {
    result.push( function() {console.log(&#39;item&#39; + i + &#39; &#39; + arr[i])} );
  }
  return result;
}
 
var fnlist = buildArr([1,2,3]);
fnlist[1](); // item3 undefined
Copier après la connexion

那么问题来了,如何改正呢?且看代码:

function buildArr(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) {
    result.push( (function(n) {
      return function() {
       var item = &#39;item&#39; + n;
       console.log(item + &#39; &#39; + arr[n]);
      }
    })(i));
  }
  return result;
}
 
var fnlist = buildArr([1,2,3]);
fnlist[0](); // item0 1
fnlist[1](); // item1 2
fnlist[2](); // item2 3
Copier après la connexion

   

我们可以用一个自执行函数将i绑定,这样i的每一个状态都会被存储,答案就和我们预期的一样了。

所以以后在使用闭包的时候遇到循环变量我们要习惯性的想到用自执行函数来绑定它。

以上就是我对闭包的理解,如果有什么意见或建议希望我们能在评论区多多交流。感谢,共勉。


Déclaration de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

Comment utiliser JS et Baidu Maps pour implémenter la fonction Map Pan Comment utiliser JS et Baidu Maps pour implémenter la fonction Map Pan Nov 21, 2023 am 10:00 AM

Comment utiliser JS et Baidu Map pour implémenter la fonction de panoramique de la carte Baidu Map est une plate-forme de services cartographiques largement utilisée, souvent utilisée pour afficher des informations géographiques, le positionnement et d'autres fonctions dans le développement Web. Cet article explique comment utiliser JS et l'API Baidu Map pour implémenter la fonction de panoramique de la carte et fournit des exemples de code spécifiques. 1. Préparation Avant d'utiliser l'API Baidu Map, vous devez d'abord demander un compte de développeur sur Baidu Map Open Platform (http://lbsyun.baidu.com/) et créer une application. Création terminée

Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies avec PHP et JS Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies avec PHP et JS Dec 17, 2023 pm 06:55 PM

Outils essentiels pour l'analyse boursière : découvrez les étapes pour dessiner des graphiques en bougies en PHP et JS. Des exemples de code spécifiques sont nécessaires. Avec le développement rapide d'Internet et de la technologie, le trading d'actions est devenu l'un des moyens importants pour de nombreux investisseurs. L'analyse boursière est une partie importante de la prise de décision des investisseurs, et les graphiques en bougies sont largement utilisés dans l'analyse technique. Apprendre à dessiner des graphiques en bougies à l'aide de PHP et JS fournira aux investisseurs des informations plus intuitives pour les aider à prendre de meilleures décisions. Un graphique en chandeliers est un graphique technique qui affiche les cours des actions sous forme de chandeliers. Il montre le cours de l'action

Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS Recommandé : Excellent projet de détection et de reconnaissance des visages open source JS Apr 03, 2024 am 11:55 AM

La technologie de détection et de reconnaissance des visages est déjà une technologie relativement mature et largement utilisée. Actuellement, le langage d'application Internet le plus utilisé est JS. La mise en œuvre de la détection et de la reconnaissance faciale sur le front-end Web présente des avantages et des inconvénients par rapport à la reconnaissance faciale back-end. Les avantages incluent la réduction de l'interaction réseau et de la reconnaissance en temps réel, ce qui réduit considérablement le temps d'attente des utilisateurs et améliore l'expérience utilisateur. Les inconvénients sont les suivants : il est limité par la taille du modèle et la précision est également limitée ; Comment utiliser js pour implémenter la détection de visage sur le web ? Afin de mettre en œuvre la reconnaissance faciale sur le Web, vous devez être familier avec les langages et technologies de programmation associés, tels que JavaScript, HTML, CSS, WebRTC, etc. Dans le même temps, vous devez également maîtriser les technologies pertinentes de vision par ordinateur et d’intelligence artificielle. Il convient de noter qu'en raison de la conception du côté Web

Comment créer un graphique en chandeliers boursiers en utilisant PHP et JS Comment créer un graphique en chandeliers boursiers en utilisant PHP et JS Dec 17, 2023 am 08:08 AM

Comment utiliser PHP et JS pour créer un graphique en bougies boursières. Un graphique en bougies boursières est un graphique d'analyse technique courant sur le marché boursier. Il aide les investisseurs à comprendre les actions de manière plus intuitive en dessinant des données telles que le prix d'ouverture, le prix de clôture, le prix le plus élevé et le prix le plus élevé. prix le plus bas des fluctuations du prix des actions. Cet article vous apprendra comment créer des graphiques en bougies boursières en utilisant PHP et JS, avec des exemples de code spécifiques. 1. Préparation Avant de commencer, nous devons préparer l'environnement suivant : 1. Un serveur exécutant PHP 2. Un navigateur prenant en charge HTML5 et Canvas 3.

Comment utiliser JS et Baidu Maps pour implémenter la fonction de carte thermique de carte Comment utiliser JS et Baidu Maps pour implémenter la fonction de carte thermique de carte Nov 21, 2023 am 09:33 AM

Comment utiliser JS et Baidu Maps pour implémenter la fonction de carte thermique de carte Introduction : Avec le développement rapide d'Internet et des appareils mobiles, les cartes sont devenues un scénario d'application courant. En tant que méthode d'affichage visuel, les cartes thermiques peuvent nous aider à comprendre la distribution des données de manière plus intuitive. Cet article explique comment utiliser JS et l'API Baidu Map pour implémenter la fonction de carte thermique de carte et fournit des exemples de code spécifiques. Travail de préparation : Avant de commencer, vous devez préparer les éléments suivants : un compte développeur Baidu, créer une application et obtenir l'AP correspondant

Comment utiliser JS et Baidu Map pour implémenter la fonction de traitement des événements de clic sur la carte Comment utiliser JS et Baidu Map pour implémenter la fonction de traitement des événements de clic sur la carte Nov 21, 2023 am 11:11 AM

Présentation de la façon d'utiliser JS et Baidu Maps pour implémenter les fonctions de traitement des événements de clic sur la carte : dans le développement Web, il est souvent nécessaire d'utiliser des fonctions de carte pour afficher la localisation géographique et les informations géographiques. Le traitement des événements de clic sur la carte est une partie couramment utilisée et importante de la fonction de carte. Cet article explique comment utiliser JS et l'API Baidu Map pour implémenter la fonction de traitement des événements de clic de la carte et donne des exemples de code spécifiques. Étapes : Importez le fichier API de Baidu Map. Tout d’abord, importez le fichier de l’API Baidu Map dans le fichier HTML. Cela peut être réalisé via le code suivant :

Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières Conseils de développement PHP et JS : maîtrisez la méthode de création de graphiques en bougies boursières Dec 18, 2023 pm 03:39 PM

Avec le développement rapide de la finance sur Internet, l'investissement en actions est devenu le choix de plus en plus de personnes. Dans le trading d'actions, les graphiques en bougies sont une méthode d'analyse technique couramment utilisée. Ils peuvent montrer l'évolution des cours des actions et aider les investisseurs à prendre des décisions plus précises. Cet article présentera les compétences de développement de PHP et JS, amènera les lecteurs à comprendre comment dessiner des graphiques en bougies boursières et fournira des exemples de code spécifiques. 1. Comprendre les graphiques en bougies boursières Avant de présenter comment dessiner des graphiques en bougies boursières, nous devons d'abord comprendre ce qu'est un graphique en bougies. Les graphiques en chandeliers ont été développés par les Japonais

Comment utiliser JS et Baidu Maps pour implémenter la fonction de dessin de polygones de carte Comment utiliser JS et Baidu Maps pour implémenter la fonction de dessin de polygones de carte Nov 21, 2023 am 10:53 AM

Comment utiliser JS et Baidu Maps pour implémenter la fonction de dessin de polygones cartographiques. Dans le développement Web moderne, les applications cartographiques sont devenues l'une des fonctions courantes. Dessiner des polygones sur la carte peut nous aider à marquer des zones spécifiques que les utilisateurs peuvent visualiser et analyser. Cet article explique comment utiliser JS et l'API Baidu Map pour implémenter la fonction de dessin de polygones de carte et fournit des exemples de code spécifiques. Tout d’abord, nous devons introduire l’API Baidu Map. Vous pouvez utiliser le code suivant pour importer le JavaScript de l'API Baidu Map dans un fichier HTML

See all articles