1. Portée de la fonction
1. Portée de la fonction
Cela signifie que la portée est dans une "fonction", et toutes les variables appartenant à cette fonction peuvent être utilisées et multiplexées dans toute la portée de la fonction.
fonction foo (a) {var b = 2; function bar () {// ...} var c = 3;} bar (); // Échec Console.log (A, B, C); // tous les trois ont échouéSi plusieurs identifiants dans la fonction "FOO" ci-dessus seront signalés s'ils sont placés en dehors de la fonction et accédés.
2. Exécuter l'expression de la fonction immédiatement
L'ajout de fonctions de wrapper en dehors de tout extrait de code peut "masquer" les variables internes et les définitions de fonctions, et la portée externe ne peut pas accéder à rien à l'intérieur de la fonction de wrapper.
Par exemple, la barre ci-dessus, A et d'autres identifiants. Cela protégera la variable de la contamination.
Lorsque vous écrivez des plug-ins, vous utilisez souvent immédiatement pour exécuter des expressions de fonction pour protéger les variables à l'intérieur.
var a = 2; (fonction foo () {var a = 3; console.log (a); // 3}) (); console.log (a); // 2Le premier () dans "FOO" transforme la fonction en une expression et le second () exécute cette fonction.
Il y a un terme spécial: iife, qui représente l'expression de fonction immédiatement invoquée;
1. L'utilisation avancée consiste à les appeler en fonction et à passer les paramètres dans
(fonction iife (global) {var a = 3; console.log (a); // 3Console.log (global.a); // 2}) (fenêtre);2. Un objectif changeant est d'inverser l'ordre de fonctionnement du code, qui est largement utilisé dans les projets CMD ou AMD.
(fonction iife (factory) {factory (fenêtre);}) (fonction def (global) {var a = 3; console.log (a); // 3Console.log (global.a); // 2});2. Portée du bloc
JavaScript ne prend pas en charge la portée du bloc.
pour (var i = 0; i <10; i ++) {console.log (i);}Le "i" dans le code ci-dessus équivaut à ce qui suit
var i; for (i = 0; i <10; i ++) {console.log (i);}Mais il y a des exceptions, "essai / catch", Catch est une portée de bloc.
essayez {undefined (); // Exécuter une opération illégale pour forcer une exception} catch (err) {console.log (err); // peut exécuter normalement! } console.log (err); // ReferenceError: err non trouvéES6 a changé le statu quo et introduit un nouveau mot clé LET, qui peut lier les variables à n'importe quelle portée (généralement à l'intérieur {..}). En d'autres termes, les variables déclarées pour laisser se situer implicitement dans la portée du bloc.
3. Amélioration
Le comportement de la portée de la fonction et de la portée du bloc est le même et peut être résumé comme: toute variable déclarée dans une portée sera attachée à cette portée.
1) Compilation et exécution
Toutes les déclarations de variables et de fonctions seront traitées avant de l'exécuter. Vous pouvez voir l'exemple de code suivant.
a = 2; var a; console.log (a); // 2
Ce code équivaut à:
var a; // Définition La déclaration est effectuée dans l'étape de compilation A = 2; // La déclaration d'attribution sera laissée en place pour attendre la console d'étape d'exécution.log (a);
2) Priorité de la fonction
La fonction sera d'abord promue, puis la variable sera.
foo (); // 1var foo; fonction foo () {console.log (1);} foo = function () {console.log (2);};L'expression de la fonction var foo, bien qu'avant la déclaration de fonction foo (), est une déclaration en double (et donc ignorée), car la déclaration de fonction sera promue avant la variable normale.
Et le code ci-dessus équivaut à:
fonction foo () {console.log (1);} foo (); // 1foo = function () {console.log (2);};4. Clôture
Les fermetures se réfèrent aux fonctions qui ont accès à des variables dans une autre portée de fonction. La façon la plus courante de créer des fermetures est de créer une autre fonction dans une fonction.
L'accès aux variables locales de cette fonction à travers une autre fonction, l'utilisation de fermetures peut percer le domaine de la chaîne d'action et passer des variables et des méthodes à l'intérieur de la fonction à l'extérieur
Caractéristiques de fermeture:
1. Les fonctions sont imbriquées intrinsèquement
2. Les fonctions internes peuvent se référer aux paramètres et variables externes
3. Les paramètres et variables ne seront pas collectés par le mécanisme de collecte des ordures
1) Définition
Lorsqu'une fonction peut se souvenir et accéder à la portée qu'il est située, une fermeture est générée, même si la fonction est exécutée en dehors de la portée actuelle.
fonction foo () {var a = 2; function bar () {console.log (a);} return bar;} var baz = foo (); baz (); // 2 - C'est l'effet de la fermeture.1. Attribuez la fonction "bar" à "baz" et exécutez "baz". La portée actuelle n'est pas dans la portée de la "barre", mais elle peut être exécutée.
2. La fermeture empêchera également la collecte des ordures. Lorsque le "FOO" est exécuté, la portée interne existe toujours. De cette façon, le "baz" peut être exécuté.
2) Passez la fonction comme paramètre
fonction foo () {var a = 2; fonction baz () {console.log (a); // 2} bar (baz);} Fonction Bar (fn) {fn (); // C'est la fermeture! }Passez la fonction interne baz à la barre, et lorsque cette fonction interne est appelée (fn), la fermeture de la portée interne de foo (), il peut être observé car il peut accéder a.
Si vous traitez une fonction comme un type de valeur au premier niveau et la passez partout, vous verrez l'application des fermetures dans ces fonctions.
Dans les minuteries, les auditeurs d'événements, les demandes AJAX, la communication croisée, les travailleurs Web ou toute autre tâche asynchrone (ou synchrone), tant que la fonction de rappel est utilisée, elle utilise en fait des fermetures!
3) Boucles et fermetures
pour (var i = 1; i <= 5; i ++) {setTimeOut (fonction Timer () {console.log (i);}, i * 1000);}Chaque fois qu'il est imprimé, il aura 6 ans et le rappel de la fonction de retard ne sera exécuté qu'à la fin de la boucle.
Selon le fonctionnement de la portée, la réalité est que bien que les cinq fonctions de la boucle soient définies séparément dans chaque itération, elles sont toutes enfermées dans une portée globale partagée, donc il n'y a en fait qu'un seul i.
Utilisez maintenant les fermetures pour implémenter les différentes imprimes I à chaque fois.
for (var i = 1; i <= 5; i ++) {(function (j) {setTimeout (function timer () {console.log (j);}, j * 1000);}) (i);}Iife crée des portées en déclarant et en exécutant immédiatement une fonction. Le rappel dans Settimeout peut se souvenir de la portée actuelle, et le paramètre "J" dans chaque portée est différent.
Ce qui précède est une explication détaillée de la portée, de l'amélioration et de la fermeture les plus déroutantes en Javascript que l'éditeur vous présente. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!