Maison >interface Web >js tutoriel >Quelle est la différence entre les fermetures Java et JavaScript

Quelle est la différence entre les fermetures Java et JavaScript

醉折花枝作酒筹
醉折花枝作酒筹original
2021-07-22 14:02:422031parcourir

La différence est la suivante : 1. La fermeture de JavaScript est en fait une fonction définie à l'intérieur d'une fonction (parce qu'il s'agit d'une fonction enfant, elle peut lire les variables internes de la fonction parent) 2. La fermeture de Java peut utiliser une méthode comme variable To ); store, cette méthode a la possibilité d’accéder aux variables libres de la classe.

Quelle est la différence entre les fermetures Java et JavaScript

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

1. Fermetures en Javascript :

1. Portée des variables

Pour comprendre les fermetures, vous devez d'abord comprendre la portée des variables spéciales de Javascript.

Il existe deux types de portées de variables : les variables globales et les variables locales.

La particularité du langage Javascript est que les variables globales peuvent être lues directement à l'intérieur de la fonction

 var n=999;
 function f1(){
   alert(n);
 }
  f1(); // 999

Par contre, les variables locales au sein de la fonction ne peuvent pas être lues en dehors de la fonction.

 function f1(){
   var n=999;
 }
  alert(n); // error

Il y a une chose à noter ici. Lorsque vous déclarez des variables dans une fonction, vous devez utiliser la commande var. Si vous ne l'utilisez pas, vous déclarez en fait une variable globale !

 function f1(){
   n=999;
 }
  f1();
  alert(n); // 999

2. Comment lire des variables locales de l'extérieur

Pour diverses raisons, nous avons parfois besoin d'obtenir des variables locales dans une fonction. Cependant, comme mentionné précédemment, cela n’est pas possible dans des circonstances normales et ne peut être réalisé que grâce à des solutions de contournement.

C'est-à-dire définir une fonction à l'intérieur de la fonction.

  function f1(){
    n=999;
    function f2(){
      alert(n); // 999
    }
 }

Puisque f2 peut lire les variables locales dans f1, alors tant que f2 est utilisé comme valeur de retour, ne pouvons-nous pas lire ses variables internes en dehors de f1 ?

  function f1(){
    n=999;
    function f2(){
      alert(n);
   }
   return f2;
 }
 var result=f1();
 result(); // 999

3. Le concept de fermeture

La fonction f2 ci-dessus est une fermeture. Une fermeture est en fait une fonction définie à l'intérieur d'une fonction (puisqu'il s'agit d'une fonction enfant, elle peut lire les variables internes de la fonction parent).

Par essence, la fermeture est un pont reliant l'intérieur d'une fonction à l'extérieur de la fonction.

4. Le but de la fermeture

1. Vous pouvez lire les variables à l'intérieur de la fonction

2. Laissez les valeurs de ces variables (variables référencées par la fermeture) rester toujours en mémoire.

  function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
 }
 var result=f1();
 result(); // 999
 nAdd();
 result(); // 1000

Dans ce code, le résultat est en fait la fonction de fermeture f2. Il a été exécuté deux fois, la première fois, la valeur était de 999, la deuxième fois, la valeur était de 1 000. Cela prouve que la variable locale n dans la fonction f1 est toujours stockée en mémoire et n'est pas automatiquement effacée après l'appel de f1.

Pourquoi cela se produit-il ? La raison en est que f1 est la fonction parent de f2 et que f2 est affecté à une variable globale, ce qui fait que f2 est toujours en mémoire, et l'existence de f2 dépend de f1, donc f1 est toujours en mémoire et ne sera pas supprimé. une fois l'appel terminé, recyclé par le mécanisme de récupération de place (garbage collection).

Un autre point remarquable dans ce code est la ligne "nAdd=function(){n+=1}". Tout d'abord, le mot-clé var n'est pas utilisé avant nAdd, donc nAdd est une variable globale, pas une variable locale. Deuxièmement, la valeur de nAdd est une fonction anonyme, et cette fonction anonyme elle-même est également une fermeture, donc nAdd est équivalent à un setter, qui peut opérer sur des variables locales à l'intérieur de la fonction en dehors de la fonction.

5. Points à noter lors de l'utilisation des fermetures

1. Étant donné que les fermetures entraîneront le stockage des variables de la fonction en mémoire, la consommation de mémoire est très importante, donc les fermetures ne peuvent pas être abusées

2. Les fermetures seront dans En dehors de la fonction parent, modifiez la valeur de la variable à l'intérieur de la fonction parent.

6. Scénarios d'application des fermetures

1. Protégez les variables dans les fonctions. En prenant l'exemple initial comme exemple, i dans la fonction a 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. Toujours comme dans l'exemple précédent, 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.

2. Fermeture en Java

1. La définition de la fermeture en Java

. Définition : Une fermeture peut stocker une méthode sous forme de variable. Cette méthode a la capacité d'accéder aux variables libres de la classe.

Le langage Java lui-même ne supporte pas officiellement les fermetures, mais il permet de simuler les fermetures (classes internes + interfaces). Les fermetures peuvent être implémentées à l'aide de classes internes anonymes.

Comment permettre à cet objet ordinaire d'accéder aux variables libres de sa classe ? Classe intérieure. La classe interne peut accéder à toutes les propriétés et méthodes de la classe externe.

Masquer l'implémentation spécifique est l'une des fonctions de la classe interne. Comment s'assurer que l'implémentation spécifique est masquée tout en passant la fermeture à un usage externe ? Laissez la classe interne implémenter l'interface commune, puis convertissez l'objet de classe interne en type d'interface.

2. Implémentation de code simple :

  	public final static String name = "纯牛奶";// 名称


		private static int num = 16;// 数量


		public Milk() {
			System.out.println(name + ":16/每箱");
		}


		/**
		 * 闭包
		 * 
		 * @return 返回一个喝牛奶的动作
		 */
		public Active HaveMeals() {
			return new Active() {
				public void drink() {
					if (num == 0) {
						System.out.println("木有了,都被你丫喝完了.");
						return;
					}
					num--;
					System.out.println("喝掉一瓶牛奶");
				}
			};
		}


		/**
		 * 获取剩余数量
		 */
		public void currentNum() {
			System.out.println(name + "剩余:" + num);
		}
	}


	/**
	 * 通用接口
	 */
	interface Active {
		void drink();
	}  
	
	//闭包的使用
	public class Person {   
		public static void main(String[] args) {  
			//买一箱牛奶  
			Milk m = new Milk(); 
			Active haveMeals = m.HaveMeals();
			//没事喝一瓶  
			haveMeals.drink();  
			//有事喝一瓶  
			haveMeals.drink(); 
			//看看还剩多少?  
			m.currentNum();  
		}   
	}

Résumé :

1. Les fermetures n'ont pas été beaucoup utilisées dans les projets réels, je ne peux donc pas commenter leur qualité.

2. Il est recommandé d'utiliser les fermetures de manière raisonnable, de ne pas les utiliser complètement, et de ne pas en abuser.

3. Attention particulière : la fermeture empêchera le recyclage des ressources. Comme dans l'exemple ci-dessus, si m est défini sur null dans la méthode main et que vous continuez à appeler la méthode drink en utilisant haveMeals, une bouteille de lait sera toujours. consommé, indiquant que l'objet Lait n'a pas été libéré.

【Apprentissage recommandé : Tutoriel avancé javascript

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