Maison  >  Article  >  interface Web  >  Explication détaillée de l'utilisation de la portée javascript et des connaissances de fermeture_Basic

Explication détaillée de l'utilisation de la portée javascript et des connaissances de fermeture_Basic

WBOY
WBOYoriginal
2016-05-16 16:51:11924parcourir

L'imbrication des portées formera une chaîne de portées, et l'imbrication des fonctions formera une fermeture. Les fermetures et les chaînes de portée sont l'une des fonctionnalités importantes qui distinguent JavaScript des autres langages.

Portée
Il existe deux types de portée en JavaScript : la portée de la fonction et la portée globale.

Les variables déclarées dans une fonction et les paramètres de la fonction partagent la même portée, c'est-à-dire la portée de la fonction. Un exemple simple de portée de fonction :

Copier le code Le code est le suivant :

function foo() {
var bar = 1 ;
{
var bar = 2;
}
barre de retour
}

Contrairement à d'autres langages à portée de bloc tels que C, cela renverra toujours 2 .

La portée globale, pour les navigateurs, peut être comprise comme l'objet window (Node.js est global) :

Copier le code Le code est le suivant :

var bar = 1;
function foo() {}
alert(window.bar); // 1
alert(window.foo); ) ; // "fonction foo() {}"

La variable bar et la fonction foo appartiennent à la portée globale et sont toutes deux des attributs de window.

Chaîne de portée
Lors de l'accès à une variable en JavaScript, elle partira des variables et paramètres locaux et parcourra la portée étape par étape jusqu'à ce qu'elle atteigne la portée globale.

Copier le code Le code est le suivant :

var scope = 0, zero = "global -scope" ;
(function(){
var scope = 1, one = "scope-1";
(function(){
var scope = 2, two = "scope-2 ";
(function(){
var scope = 3, three = "scope-3";
scope-1 global-scope
console.log([trois, deux, un, zéro ].join(" "));
              console.log(scope); // 3
          })();
console.log(typeof two); // non défini
console.log(scope); // 1
})();
console.log(typeof one); 🎜>console.log(scope); // 0



Dans la fonction la plus interne, chaque variable peut être parcourue étape par étape et sortie. Dans l'avant-dernière couche de fonctions, la variable trois ne peut pas être trouvée par parcours, donc la sortie est indéfinie.
Pour donner un exemple simple, lorsque vous allez dépenser de l'argent pour acheter quelque chose, vous toucherez d'abord votre portefeuille. Si vous ne l'avez pas, vous pouvez le demander à votre père. ça, tu peux demander à ton grand-père... Et quand ton père n’a pas d’argent pour acheter quelque chose, il ne viendra pas te le demander.

Fermeture

Dans une fonction, la définition d'une autre fonction est appelée imbrication de fonctions. L'imbrication des fonctions formera une fermeture.

Les fermetures et les chaînes de portées se complètent. L'imbrication des fonctions crée non seulement plusieurs portées dans une relation en chaîne, mais forme également une fermeture.



Copier le code

Le code est le suivant :function bind(func, target) { return function() {
func.apply(target, arguments);
};
}



Alors, comment comprenez-vous la fermeture ?
Les fonctions externes ne peuvent pas accéder aux fonctions intégréesLes fonctions externes ne peuvent pas accéder aux paramètres et variables des fonctions intégrées

Mais les fonctions intégrées peuvent accéder aux paramètres et variables des fonctions externes

En d'autres termes : les fonctions intégrées Contient la portée du fonction externe

Regardons l'exemple de chaîne de portée mentionné précédemment, en le comprenant cette fois du point de vue de la fermeture :



Copier le code

Le code est le suivant :

var scope = 0, zéro = "global-scope";
(function(){
var scope = 1, one = "scope-1";
(function() {
var scope = 2, two = "scope-2";
(function(){
var scope = 3, three = "scope-3";
// scope-3 scope -2 scope-1 global-scope
console.log([trois, deux, un, zéro].join(" "));
console.log(scope); // 3
}) ();
console.log(typeof three); // non défini
console.log(scope); // 2
})();
console.log(typeof two); / non défini
console.log(scope); // 1
})();
console.log(typeof one); // non défini
console.log(scope);

La fonction la plus interne peut accéder à toutes les variables définies en interne et en externe. L'avant-dernière fonction ne peut pas accéder à la variable la plus interne. En même temps, l'opération d'affectation de scope = 3 dans la couche la plus interne n'affecte pas la variable externe du même nom.

Comprenons la clôture sous un autre angle :

Chaque fois qu'une fonction externe est appelée, la fonction intégrée sera créée une fois
Lors de sa création, la portée de la fonction externe (y compris les variables locales, les paramètres, etc. le contexte) deviendra chaque fonction intégrée. objet. fait partie de l’état interne, même après que la fonction externe a terminé son exécution et s’est terminée
Voir l’exemple suivant :

Copier le code Le code est le suivant :

var i, list = [];
for (i = 0; i < 2; i = 1) {
list.push(function(){
console.log(i);
});
}
liste .forEach(function(func){
func();
});

Nous obtiendrons "2" deux fois au lieu des "1" et "2" attendus. En effet, la variable à laquelle j'ai accédé par les deux fonctions de la liste est la même variable dans la portée supérieure.

Modifions le code pour utiliser des fermetures pour résoudre ce problème :

Copier le code Le code est le suivant :

var i, list = [];
for (i = 0; i < 2; i = 1) {
list.push((function(j){
) return function(){
console.log(j);
} ;
})(i));
}
list.forEach(function(func){
func();
});

La "fonction d'exécution immédiate" externe reçoit une variable de paramètre i, qui existe sous la forme de paramètre j au sein de sa fonction. Elle pointe vers la même référence que le nom j dans la fonction interne renvoyée. Une fois la fonction externe exécutée et sortie, le paramètre j (sa valeur est la valeur actuelle de i à ce moment) fait partie de l'état de sa fonction interne et est enregistré.

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