fonction
Format de fonction
function getProtTynames (o, / * Facultatif * / a) {a = a || []; pour (var p dans o) {a.push (p);} return a;}Demandeur
func.Caller renvoie l'appelant de fonction
fonction callfunc () {if (callfunc.Caller) {alert (callfunc.Caller.toString ());} else {alert ("no function calm");}} function handleCaller () {callfunc ();} handleCaller (); // ne return handlercalfunc (); //callee
Méthode anonyme Appel récursif
alert ((fonction (x) {if (x <=) return; return x * arguments.callee (x -);} ())); //portée
Tout le monde connaît la portée. Aujourd'hui, je vais parler du problème de fermeture et comprendre le problème de fermeture à fond.
<Script> var global = "Global Scope"; // Il s'agit de la fonction de portée globale SPOPE () {var scope = "Local Scope"; // Il s'agit de la portée de retour locale; // La portée retournée est une variable locale} </ script>1.: Les variables globales définies sont également accessibles à l'intérieur de la fonction . Lorsque la variable locale définie et le nom de la variable globale sont les mêmes, la variable locale masquera la variable globale et ne détruira pas la valeur de la variable globale.
var scope = "Global Scope"; fonction f () {var scope = "Local Scope"; Retour Scope;} alert (f ()); // Scopelert local (Scope); // Scope globale;Ce qui précède est en effet facile à comprendre, non?
2. Les variables globales peuvent être déclarées sans VAR , mais les variables locales doivent être déclarées avec VAR. Si les variables locales n'utilisent pas la déclaration VAR, le compilateur sera par défaut en tant que variable globale.
<span style = "Line-Height:.
Cependant, les variables globales n'utilisent pas de déclarations VAR et ne sont disponibles que pour le mode non stricte. Si un mode strict est utilisé, une erreur sera signalée.
<Script> "Utiliser strict"; scope = "Global Scope"; fonction f () {scope = "Local Scope"; return Scope;} alert (f ()); // Scopelert local (Scope); // Scope locale </ script>Par conséquent, il est recommandé de ne pas omettre VAR lors de la déclaration des variables, car cela peut éviter les problèmes inutiles.
3. Il est normal de déclarer à l'avance . Qu'est-ce qui est à l'avance.
<Script> "Utiliser Strict"; Scope; Console.log (Scope); var Scope = "Global Scope"; Console.log (Scope); </Script>
Cela peut être considéré comme le premier à imprimer indéfini. Oui, il n'a pas encore été attribué de valeur. L'affectation suivante peut déterminer la portée globale.
Ce n'est pas faux, mais pourquoi cela se produit-il? Une variable ne devrait-elle pas être définie avant de pouvoir être utilisée?
Ici, je vais vous parler de la chaîne de portée. JavaScript est une langue de portée lexicale.
1. Une chaîne de portée est une liste d'objet ou liée. Cet ensemble de code définit les variables "dans la portée" de ce code. Lorsque JavaScript doit trouver la portée variable, elle se développera et recherchera à partir du premier objet de la chaîne. Si le premier objet est de portée, la valeur de cet objet sera directement renvoyée. S'il n'existe pas, il continuera de rechercher le deuxième objet jusqu'à ce qu'il soit trouvé. Si la variable n'est pas trouvée sur la chaîne de portée, une erreur sera lancée.
Nous pouvons exprimer cette chaîne de fonction comme suit: Recherchez la portée-> Fenêtre (objet global), puis la portée est définie. Cependant, l'opération d'attribution n'a pas été effectuée et l'opération d'attribution a été effectuée plus tard, donc la valeur n'est pas définie pour le moment.
4. C'est plus déroutant. Quelle est la valeur imprimée?
<Script> "Utiliser strict"; var scope = "Global Scope"; fonction f () {console.log (scope); var scope = "Local Scope"; console.log (scope);} f (); </cript>Voir ce code: Si vous êtes imprudent, vous pouvez écrire la mauvaise réponse:
1. Portée gluée
2. Portée locale
Analyse: Déclarer les variables globales. Lorsque dans l'organisme de fonction, le premier représente la variable globale, donc Global est imprimé, et le second définit les variables locales, couvrant la portée globale, de sorte que la portée locale est imprimée.
Une telle analyse est complètement correcte dans C # Java. Mais l'analyse ici est en effet erronée.
Cela montre qu'avant ce problème, regardons d'abord une question.
Cette phrase est très importante: les variables globales sont toujours définies dans le programme. Les variables locales sont toujours définies dans le corps de la fonction qui la déclare et les fonctions qu'il niche.
Si vous travaillez dans une langue de haut niveau, vous êtes exposé à JavaScript un peu inadapté à sa définition de portée. Je suis le même. Jetons un coup d'œil à un exemple:
<Script> var g = "Global Scope"; fonction f () {for (var i =; i <; i ++) {for (var j =; j <; j ++) {;} console.log (j);} console.log (i);} console.log (g); f (); </ script>Quel est le résultat de l'impression?
Vous voyez que {} représente un bloc d'instructions, et le bloc d'instructions est dans la portée du même bloc, vous pouvez donc deviner que les valeurs J et I ont été libérées en mémoire, donc le résultat doit être indéfini.
Le vrai résultat peut vous décevoir.
Pourquoi est-ce arrivé? Mon expression a commencé comme vous.
Découvrez la phrase que je vous ai demandé de vous souvenir maintenant. . . Les variables globales sont toujours définies dans le programme. Les variables locales sont toujours définies dans le corps de la fonction qui la déclare et les fonctions qu'il niche.
Pour être précis, les paramètres de la fonction appartiennent également à la catégorie des variables locales. Cette phrase est également très importante! ! !
Cette phrase signifie à peu près que tant qu'une variable définie à l'intérieur d'une fonction est valide dans toute la fonction. Le résultat n'est donc pas difficile à comprendre. En regardant notre question, comprenez-vous?
La chaîne d'action a également les définitions suivantes:
1. La chaîne d'action est composée d'un objet global.
2. Dans le corps de fonction qui ne contient pas de nidification, il y a deux objets sur la chaîne d'action. Le premier objet définit les paramètres de fonction et les variables locales, et le second est l'objet global.
3. Dans un corps de fonction imbriqué, il y a au moins trois objets sur la chaîne d'action.
Lorsqu'une fonction est définie, une chaîne de portée sera enregistrée.
Lorsque cette fonction est appelée, il crée un nouvel objet pour stocker ses variables locales et ajoute cet objet à la chaîne d'action enregistrée. En même temps, créez une nouvelle chaîne de fonctions plus longue représentant des appels de fonction.
Pour les fonctions imbriquées, lorsque la fonction externe est appelée, la fonction interne sera à nouveau redéfinie. Parce que chaque fois qu'une fonction externe est appelée, la chaîne d'action est différente. Les fonctions internes ont des différences subtiles chaque fois qu'elles sont définies. Chaque fois que la fonction externe est appelée, le code de la fonction interne est le même et la portée du code associé est également différente.
Fermeture
Après l'avoir fait si longtemps, j'ai finalement pu en parler, mais analysons la portée auparavant.
<script> var nommeg = "global" var g = fonction f () {console.log (name); fonction demo () {console.log ("demo =" + name);} var name = ""; function démo () {var name = ""; console.log ("demo =" + name); nommeg);} démo (); démo (); demo ();}; g (); </cript>Nous analysons selon la chaîne d'action:
Appelez Demo0, Demo0 () -> Rechercher le nom, introuvable -> f (), retourne
Appelez Demo1, Demo1 () -> trouver le nom, trouver, retourner
Appelez Demo2, Demo2 () -> Recherchez NameG, introuvable -> f () pour trouver Nomg, introuvable -> fenêtre pour trouver Nameg, retourne.
Regardez cet exemple:
<script> function f () {var count =; return {compter: function () {return count ++;}, reset: function () {return count =;}}} var d = f (); var c = f (); console.log ("d premier appel:" + d.counter ()); // console ("c premier appel:" + c.counter ()); Appel: "+ C.Counter ()); // </ Script>Comme vous pouvez le voir dans cet exemple, j'ai fait une opération de comptage et de zéro.
Deux instances d'objet de F sont créées, chacune avec sa propre chaîne de portée, de sorte que leurs valeurs ne se affectent pas. Lorsque C est appelé la deuxième fois, la valeur de comptage est enregistrée car l'objet C n'est pas détruit. Ce n'est qu'après avoir compris cet exemple que l'exemple suivant sera plus facile à comprendre.
Tout le monde devrait être très clair sur ce processus. Alors, regardons le problème de fermeture. J'ai défini quatre boutons et cliquez sur chaque bouton pour retourner le nom de la réponse.
<body> <script> function btninit () {for (var i =; i <; i ++) {var btn = document.getElementyid ("btn" + i); btn.addeventListener ("cliquez", function () {alert ("btn" + i);});}} window.onload = btnin; id = "btn"> btn </ bouton> <bouton id = "btn"> btn </ bouton> <bouton id = "btn"> btn </ bouton> <bouton id = "btn"> btn </vutton> </v> </ body>Cliquez pour s'exécuter, mais le résultat est tout BTN5;
Nous nous sommes assis avec l'analyse tout à l'heure. Tout d'abord, nous devons appeler la fonction anonyme -> trouver i, introuvable -> btNinit (), et trouvé i dans la boucle pour. venez. Nous savons que seul l'appel de fonction est publié est publié, et le I in For est toujours visible, donc la dernière valeur I est conservée. Alors comment le résoudre.
Pour résoudre le problème que la valeur I n'est pas toujours visible dans la fonction, nous devons utiliser le nidification de la fonction et y passer la valeur I.
fonction btNinit () {for (var i =; i <; i ++) {(function (data_i) {var btn = document.getElementById ("btn" + data_i); btn.addeventListener ("click", function () {alert ("btn" + data_i);});} (i));}}En regardant le code modifié, exécutez d'abord le premier pour et créez un objet. Nous exécutons d'abord la fonction anonyme -> data_i, mais pas trouvé -> fonction (data_i), puis exécutez à nouveau pour créer un objet. Les règles de clôture disent qu'ils ne se affectent pas mutuellement. Ainsi, le résultat correct peut être obtenu.
Ce qui précède est la fonction JavaScript doit savoir (9) que l'éditeur vous présente. En parlant des connaissances pertinentes sur les problèmes de fermeture, 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!