Scoping et levage de la fonction Javascript


89

Je viens de lire un excellent article sur JavaScript Scoping and Hoisting par Ben Cherry dans lequel il donne l'exemple suivant:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}
b();
alert(a);

En utilisant le code ci-dessus, le navigateur alertera "1".

Je ne sais toujours pas pourquoi il renvoie "1". Certaines des choses qu'il dit viennent à l'esprit comme: Toutes les déclarations de fonction sont hissées vers le haut. Vous pouvez définir une variable à l'aide de function. Ne clique toujours pas pour moi.

Réponses:


120

Le levage de fonction signifie que les fonctions sont déplacées vers le haut de leur portée. C'est,

function b() {  
   a = 10;  
   return;  
   function a() {} 
} 

sera réécrit par l'interprète à ceci

function b() {
  function a() {}
  a = 10;
  return;
}

Bizarre, hein?

De plus, dans ce cas,

function a() {}

s'est comporté de la même manière que

var a = function () {};

Donc, en substance, c'est ce que fait le code:

var a = 1;                 //defines "a" in global scope
function b() {  
   var a = function () {}; //defines "a" in local scope 
   a = 10;                 //overwrites local variable "a"
   return;      
}       
b();       
alert(a);                 //alerts global variable "a"

2
Donc toutes les déclarations de fonction sont finalement assignées à une variable?
dev.e.loper

15
@ dev.e.loper Oui, en Javascript, les fonctions sont des objets de première classe, tout comme les chaînes et les nombres. Cela signifie qu'ils sont définis comme des variables et peuvent être passés à d'autres fonctions, être stockés dans des tableaux, etc.
Peter Olson

4
En aucun cas le corps de la fonction n'est "réécrit". Les différentes normes ECMAScript indiquent clairement que les déclarations de variables et de fonctions sont traitées avant le début de l'exécution du code. C'est-à-dire que rien n'est déplacé , il s'agit de l'ordre d'exécution (d'où mon aversion pour le terme «hissage», qui induit un mouvement ou un réarrangement). Dans votre code réécrit, la déclaration var adoit être avant la déclaration de fonction et l'affectation a = 1doit être après. Mais notez que cela n'est pas spécifié pour se produire réellement par l'analyseur, le tokeniseur, l'interpréteur, le compilateur, peu importe, c'est juste un équivalent.
RobG

3
@RobG Bien sûr, je suppose que vous pourriez appeler la description un petit "mensonge aux enfants" , mais à la fin le comportement est le même, que le code soit littéralement réorganisé ou que l'ordre d'exécution soit simplement réorganisé. Ce qui se passe réellement dans les coulisses est davantage une préoccupation académique et pourrait même dépendre de la mise en œuvre.
Peter Olson

7
"De plus, dans ce cas, function a() {}s'est comporté de la même manière que var a = function () {};"  - ceci est incorrect de deux manières: d'abord, si quelque chose aurait été var a = function a() {};(la fonction n'est en fait pas anonyme), deuxièmement, ces deux formes ne sont pas interchangeables, car à partir de var a = function a() {};seule la var a;partie aurait été hissée. La a = function a() {};pièce aurait toujours été derrière la déclaration de retour. Étant donné que le formulaire d'origine est une déclaration de fonction et non une expression de fonction, il est en fait hissé dans son ensemble.
user4642212

6

Ce que vous devez vous rappeler, c'est qu'il analyse l'ensemble de la fonction et résout toutes les déclarations de variables avant de l'exécuter. Alors....

function a() {} 

devient vraiment

var a = function () {}

var a la force dans une portée locale, et la portée de la variable s'étend sur toute la fonction, donc la variable globale a est toujours 1 parce que vous avez déclaré a dans une portée locale en en faisant une fonction.


5

La fonction aest hissée à l'intérieur de la fonction b:

var a = 1; 
function b() { 
   function a() {} 
   a = 10; 
   return;
} 
b(); 
alert(a);

ce qui revient presque à utiliser var:

var a = 1; 
function b() { 
   var a = function () {};
   a = 10; 
   return;
} 
b(); 
alert(a);

La fonction est déclarée localement et la configuration ane se produit que dans la portée locale, pas dans la variable globale.


1
cette ligne "var a = function () {};" rend tout clair .. fondamentalement JavaScript est un langage dynamique et "function" est aussi un objet en JavaScript.
refactor

3
  1. La déclaration de fonction function a(){}est levée en premier et elle se comporte comme var a = function () {};, par conséquent, la portée locale aest créée.
  2. Si vous avez deux variables avec le même nom (une en global, une autre en local), la variable locale a toujours la priorité sur la variable globale.
  3. Lorsque vous définissez a=10, vous définissez la variable locale a, pas la variable globale.

Par conséquent, la valeur de la variable globale reste la même et vous obtenez, alerté 1


1

function a() { }est une instruction de fonction, qui crée une avariable locale à la bfonction.
Les variables sont créées lorsqu'une fonction est analysée, que levar instruction de fonction ou soit exécutée.

a = 10 définit cette variable locale.


a = 10définit en fait une variable dans la portée globale lorsque la fonction best exécutée sauf si vous ajoutez "use strict"(dans des environnements tels que la prise en charge de cette directive).
Sean Vieira

@Sean: Non, car l'instruction de fonction crée un identifiant local.
SLaks

... et ... vous avez raison. Je n'avais pas réalisé cette conséquence particulière du levage de fonction. Merci!
Sean Vieira

1

Quelle est la pomme de discorde dans ce petit bout de code?

Cas 1:

Incluez la function a(){}définition dans le corps de function bcomme suit.logs value of a = 1

var a = 1;
function b() {
  a = 10;
  return;

  function a() {}
}
b();
console.log(a); // logs a = 1

Cas 2

Excluez la function a(){}définition à l'intérieur du corps de function bcomme suit.logs value of a = 10

var a = 1;
function b() {
  a = 10;  // overwrites the value of global 'var a'
  return;
}
b();
console.log(a); // logs a = 10

L'observation vous aidera à réaliser cette déclaration console.log(a) enregistre les valeurs suivantes.

Cas 1 : a = 1

Cas 2: a = 10

Posits

  1. var a a été défini et déclaré lexicalement dans la portée globale.
  2. a=10 Cette instruction réaffecte la valeur à 10, elle se trouve lexicalement à l'intérieur de la fonction b.

Explication des deux cas

En raison d' function definition with name propertyun est le même que le variable a. L' variable aintérieur function body bdevient une variable locale. La ligne précédente implique que la valeur globale de a reste intacte et que la valeur locale de a est mise à jour à 10.

Donc, ce que nous avons l'intention de dire, c'est que le code ci-dessous

var a = 1;
function b() {
  a = 10;
  return;

  function a() {}
}
b();
console.log(a); // logs a = 1

Il est interprété par l'interpréteur JS comme suit.

var a = 1;
function b() {
  function a() {}
  a = 10;
  return;


}
b();
console.log(a); // logs a = 1

Cependant, lorsque nous supprimons le function a(){} definition, le value of 'a'déclaré et défini en dehors de la fonction b, cette valeur est écrasée et passe à 10 dans le cas 2. La valeur est écrasée car a=10fait référence à la déclaration globale et si elle devait être déclarée localement, nous devons avoir écrit var a = 10;.

var a = 1;
function b() {
  var a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;
}
b();
console.log(a); // logs a = 1

Nous pouvons clarifier davantage notre doute en changeant le name propertyin function a(){} definitionen un autre nom que'a'

var a = 1;
function b() {
  a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;

  function foo() {}
}
b();
console.log(a); // logs a = 1

1

Le levage est un concept fait pour nous pour le rendre plus facile à comprendre. Ce qui se passe en fait, c'est que les déclarations sont faites en premier par rapport à leurs portées et les affectations se produiront ensuite (pas en même temps).

Lorsque les déclarations se produisent, var aalors function bet à l'intérieur de cette bportée, function aest déclaré.

Cette fonction a occultera la variable a provenant de la portée globale.

Une fois les déclarations faites, les valeurs assignées commenceront, le global aobtiendra la valeur 1et le a inside function bobtiendra 10. lorsque vous le faites alert(a), il appellera la variable de portée globale réelle. Ce petit changement au code le rendra plus clair

        var a = 1;

    function b() {
        a = 10;
        return a;

        function a() { }
    }

    alert(b());
    alert(a);

1
Il est curieux que tant d'experts même dans un cours sur codeschool.com se réfèrent au levage qui n'est rien de plus qu'une vue simpliste de ce qui se passe, en fait, le levage ne se produit pas du tout. Ref: 1) developer.mozilla.org/en-US/docs/Glossary/Hoisting 2) Chapitre 5 de Secrets of the JavaScript Ninja 2 / e par john resig, bear bebeault, josip maras
adnan2nd

1

Étonnamment, aucune des réponses ici ne mentionne la pertinence du contexte d'exécution dans la chaîne de portée.

Le moteur JavaScript encapsule le code en cours d'exécution dans un contexte d'exécution. Le contexte d'exécution de base est le contexte d'exécution global. Chaque fois qu'une nouvelle fonction est appelée, un nouveau contexte d'exécution est créé et placé sur la pile d'exécution. Pensez à un cadre de pile assis sur une pile d'invocation dans d'autres langages de programmation. Dernier entré, premier sorti. Désormais, chaque contexte d'exécution a son propre environnement variable et son propre environnement externe en JavaScript.

J'utiliserai l'exemple ci-dessous comme démonstration.

1) Tout d'abord, nous entrons dans la phase de création du contexte global d'exécution. L'environnement extérieur et l'environnement variable de l'environnement lexical sont créés. L'objet global est configuré et placé en mémoire avec la variable spéciale «this» pointant vers lui. La fonction a et son code et la variable myVar avec une valeur indéfinie sont placés en mémoire dans l'environnement variable global. il est important de noter que le code de la fonction a n'est pas exécuté. Il est simplement mis en mémoire avec la fonction a.

2) Deuxièmement, c'est la phase d'exécution du contexte d'exécution. myVar n'est plus une valeur indéfinie. Il est initialisé avec la valeur 1, qui est stockée dans l'environnement variable global. La fonction a est appelée et un nouveau contexte d'exécution est créé.

3) Dans le contexte d'exécution de la fonction a, elle passe par la phase de création et d'exécution de son propre contexte d'exécution. Il a son propre environnement extérieur et son environnement variable, donc son propre environnement lexical. La fonction b et la variable myVar sont stockées dans son environnement variable. Cet environnement variable est distinct de l'environnement variable global. Puisque la fonction a se situe lexicalement (physiquement dans le code) au même niveau que le contexte d'exécution global, son environnement extérieur est le contexte d'exécution global. Ainsi, si la fonction a faisait référence à une variable qui n'est pas dans son environnement variable, elle recherchera la chaîne de portée et tentera de trouver la variable dans l'environnement variable du contexte d'exécution global.

4) La fonction b est appelée dans la fonction a. Un nouveau contexte d'exécution est créé. Puisqu'il se trouve lexicalement dans la fonction a, son environnement extérieur est a. Ainsi, quand il fait référence à myVar, puisque myVar n'est pas dans l'environnement variable de la fonction b, il cherchera dans l'environnement variable de la fonction a. Il le trouve là et console.log imprime 2. Mais si la variable n'était pas dans l'environnement variable de la fonction a, alors puisque l'environnement extérieur de la fonction a est le contexte d'exécution global, alors la chaîne de portées continuera à y chercher.

5) Une fois l'exécution des fonctions b et a terminée, elles sont extraites de la pile d'exécution. Le moteur JavaScript monothread continue son exécution dans le contexte d'exécution global. Il invoque la fonction b. Mais il n'y a pas de fonction b dans l'environnement variable global et il n'y a pas d'autre environnement externe à rechercher dans le contexte d'exécution global. Ainsi, une exception est déclenchée par le moteur JavaScript.

function a(){
  function b(){
    console.log(myVar);
  }

  var myVar = 2;
  b();
}

var myVar = 1;
a();
b();
> 2
> Uncaught ReferenceError: b is not defined

L'exemple ci-dessous montre la chaîne de portée en action. Dans l'environnement variable du contexte d'exécution de la fonction b, il n'y a pas de myVar. Il recherche donc son environnement extérieur, qui est la fonction a. La fonction a n'a pas non plus myVar dans son environnement variable. Ainsi, les recherches du moteur fonctionnent dans l'environnement externe de a, qui est l'environnement externe du contexte d'exécution global et myVar y est défini. Par conséquent, console.log imprime 1.

function a(){
  function b(){
    console.log(myVar);
  }

  b();
}

var myVar = 1;
a();
> 1

En ce qui concerne le contexte d'exécution et l'environnement lexical qui lui est associé, y compris l'environnement externe et l'environnement variable, activez la portée des variables dans JavaScript. Même si vous appelez la même fonction plusieurs fois, pour chaque appel, elle créera son propre contexte d'exécution. Ainsi, chaque contexte d'exécution aura sa propre copie des variables dans son environnement variable. Il n'y a pas de partage de variables.


0

Cela se produit parce que le nom de la variable est le même que le nom de la fonction signifie "a". Ainsi, en raison du levage de Javascript, il essaie de résoudre le conflit de nom et il retournera a = 1.

J'étais également confus à ce sujet jusqu'à ce que je lis ce post sur "JavaScript Hoisting" http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

J'espère que ça aide.


0

Voici mon récapitulatif de la réponse avec plus d'annotations et un violon d'accompagnement avec lequel jouer.

// hoisting_example.js

// top of scope ie. global var a = 1
var a = 1;

// new scope due to js' functional (not block) level scope
function b() {
    a = 10; // if the function 'a' didn't exist in this scope, global a = 10
  return; // the return illustrates that function 'a' is hoisted to top
  function a(){}; // 'a' will be hoisted to top as var a = function(){};
}

// exec 'b' and you would expect to see a = 10 in subsequent alert
// but the interpreter acutally 'hoisted' the function 'a' within 'b' 
// and in doing so, created a new named variable 'a' 
// which is a function within b's scope
b();

// a will alert 1, see comment above
alert(a);

https://jsfiddle.net/adjavaherian/fffpxjx7/


0

portée et fermeture et levage (var / fonction)

  1. scpope: la variable globale peut être accédée n'importe où (toute la portée du fichier), la variable locale n'est accessible que par la portée locale (portée de fonction / bloc)!
    Remarque: si une variable locale n'utilise pas de mots-clés var dans une fonction, elle deviendra une variable globale!
  2. fermeture: une fonction à l'intérieur de l'autre fonction, qui peut accéder à la portée locale (fonction parent) et à la portée globale, à moins que les autres ne puissent accéder à ses vars! à moins que vous ne le renvoyiez comme valeur de retour!
  3. levage: déplacez toutes les variables / fonctions déclarées / annulées vers le haut de la portée, puis affectez la valeur ou null!
    Remarque: il suffit de déplacer la déclaration, pas de déplacer la valeur!

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined



0

Levage En JavaScript signifie, les déclarations de variables sont exécutées tout au long du programme avant l'exécution de tout code. Par conséquent, déclarer une variable n'importe où dans le code équivaut à la déclarer au début.


0

Tout dépend de la portée de la variable «a». Laissez-moi vous expliquer en créant des portées sous forme d'images.

Ici, JavaScript créera 3 portées.

i) Portée mondiale. ii) Portée de la fonction b (). iii) Fonction a () portée.

entrez la description de l'image ici

Son clair lorsque vous appelez la portée de la méthode 'alert' appartient à Global à ce moment-là, donc il choisira la valeur de la variable 'a' dans la portée Global uniquement qui est 1.


0

Long Post!

Mais ça va purifier l'air!

Le fonctionnement de Java Script est qu'il implique un processus en deux étapes:

  1. Compilation (pour ainsi dire) - Cette étape enregistre les variables et les déclarations de fonction et leur portée respective. Cela n'implique pas l'évaluation de l'expression de fonction: var a = function(){}ou de l'expression de variable (comme l'attribution 3de xin case var x =3;qui n'est rien d'autre que l'évaluation de la partie RHS.)

  2. Interprète: Il s'agit de la partie exécution / évaluation.

Vérifiez la sortie du code ci-dessous pour comprendre:

//b() can be called here!
//c() cannot be called.
console.log("a is " + a);
console.log("b is " + b);
console.log("c is " + c);
var a = 1;
console.log("Now, a is " + a);
var c = function() {};
console.log("Now c is " + c);

function b() {
  //cannot write the below line:
  //console.log(e); 
  //since e is not declared.
  e = 10; //Java script interpreter after traversing from this function scope chain to global scope, is unable to find this variable and eventually initialises it with value 10 in global scope.
  console.log("e is " + e) //  works!
  console.log("f is " + f);
  var f = 7;
  console.log("Now f is " + f);
  console.log("d is " + d);
  return;

  function d() {}
}
b();
console.log(a);

Permet de le casser:

  1. Dans la phase de compilation, «a» serait enregistré sous la portée globale avec la valeur « undefined». Il en va de même pour « c», sa valeur à ce moment serait « undefined» et non le « function()». ' b' serait enregistré en tant que fonction dans la portée globale. Dans bla portée de ' f' , ' ' serait enregistré comme une variable qui ne serait pas définie à ce moment et la fonction ' d' serait enregistrée.

  2. Lorsque l'interpréteur s'exécute, les variables déclarées et function()(et non les expressions) sont accessibles avant que l'interpréteur n'atteigne la ligne d'expression réelle. Ainsi, les variables seraient imprimées ' undefined' et la fonction anonyme déclarée peut être appelée plus tôt. Cependant, essayer d'accéder à une variable non déclarée avant l'initialisation de son expression entraînerait une erreur comme:

console.log(e)
e = 3;

Maintenant, que se passe-t-il lorsque vous avez une déclaration de variable et de fonction avec le même nom.

La réponse est - les fonctions sont toujours levées avant et si la même variable de nom est déclarée, elle est traitée comme dupliquée et ignorée. N'oubliez pas que l'ordre n'a pas d'importance. Les fonctions sont toujours prioritaires. Mais pendant la phase d'évaluation, vous pouvez modifier la référence de la variable à n'importe quoi (elle stocke ce qui était la dernière affectation) Jetez un œil au code ci-dessous:

var a = 1;
console.log("a is " + a);

function b() {
  console.log("a inside the function b is " + a); //interpreter finds                                'a' as function() in current scope. No need to go outside the scope to find 'a'.
  a = 3; //a changed
  console.log("Now a is " + a);
  return;

  function a() {}
}
var a; //treated as duplicate and ignored.
b();
console.log("a is still " + a + " in global scope"); //This is global scope a.


0

Le levage est un concept comportemental de JavaScript. Le levage (disons le déplacement) est un concept qui explique comment et où les variables doivent être déclarées.

En JavaScript, une variable peut être déclarée après avoir été utilisée car les déclarations de fonction et les déclarations de variable sont toujours déplacées («hissées») de manière invisible vers le haut de leur portée contenant par l'interpréteur JavaScript.

Nous rencontrons deux types de levage dans la plupart des cas.

1. levage de déclaration variable

Permet de comprendre cela par ce morceau de code.

 a = 5; // Assign 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
 var a; // Declare a
  //output-> 5

Ici, la déclaration de la variable a sera hébergée en haut de manière invisible par l'interpréteur javascript au moment de la compilation. Nous avons donc pu obtenir la valeur d'un. Mais cette approche de déclaration de variables n'est pas recommandée car nous devrions déjà déclarer les variables en haut comme ceci.

 var a = 5; // Assign and declare 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
  // output -> 5

prenons un autre exemple.

  function foo() {
     console.log(x)
     var x = 1;
 }

est en fait interprété comme ceci:

  function foo() {
     var x;
     console.log(x)
     x = 1;
  }

Dans ce cas, x sera indéfini

Peu importe si le code a été exécuté qui contient la déclaration de variable. Prenons cet exemple.

  function foo() {
     if (false) {
         var a = 1;
     }
     return;
     var b = 1;
  }

Cette fonction se révèle être comme ça.

  function foo() {
      var a, b;
      if (false) {
        a = 1;
     }
     return;
     b = 1;
  }

Dans la déclaration de variable, seuls les ascenseurs à définition de variable, pas l'affectation.

  1. Déclaration de fonction levage

Contrairement à la variable de levage, le corps de fonction ou la valeur assignée sera également soulevé. Considérez ce code

 function demo() {
     foo(); // this will give error because it is variable hoisting
     bar(); // "this will run!" as it is function hoisting
     var foo = function () {
         alert("this would not run!!");
     }
     function bar() { 
         alert("this will run!!");
     }
 }
 demo();

Maintenant que nous avons compris le levage de variables et de fonctions, comprenons maintenant ce code.

var a = 1;
function b() {
  a = 10;
  return;
   function a() {}
}
b();
alert(a);

Ce code se révélera être comme ça.

var a = 1;                 //defines "a" in global scope
 function b() {  
   var a = function () {}; //defines "a" in local scope 
    a = 10;                 //overwrites local variable "a"
    return;      
 }       
 b();       
 alert(a); 

La fonction a () aura une portée locale dans b (). a () sera déplacé vers le haut lors de l'interprétation du code avec sa définition (uniquement en cas de levage de fonction) donc a now aura une portée locale et n'affectera donc pas la portée globale de a tout en ayant sa propre portée dans la fonction b () .


0

D'après mes connaissances, le levage se produit avec la déclaration de variable et la déclaration de fonction, par exemple:

a = 7;
var a;
console.log(a) 

Que se passe-t-il dans le moteur de JavaScript:

var a;
a = 7;
console.log(a);
// 7

Ou:

console.log(square(7)); // Output: 49
function square(n) { return n * n; }

Cela deviendra:

function square(n) { return n * n; }
console.log(square(7)); // 49

Mais les affectations telles que l'affectation de variable, l'affectation d'expression de fonction ne seront pas levées: Par exemple:

console.log(x);
var x = 7; // undefined

Cela peut devenir comme ça:

var x;
console.log(x); // undefined
x = 7;

0

Pour décrire l'hébergement en javascript en une phrase, les variables et les fonctions sont hissées au sommet de la portée dans laquelle elles sont déclarées.

entrez la description de l'image ici

Je suppose que vous êtes un débutant, pour bien comprendre le levage au début, nous avons compris la différence entre undefined et ReferenceError

 var v;
 console.log(v);
 console.log(abc);
/*
The output of the above codes are:
undefined
ReferenceError: abc is not defined*/

maintenant dans le code ci-dessous ce que nous voyons? une variable et une expression de fonction sont décleard.

<script>
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
</script>

mais l'image réelle avec la preuve que la variable et la fonction sont hissées au-dessus de la portée:

console.log(totalAmo);
console.log(getSum(8,9));
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
console.log(totalAmo);
console.log(getSum(9,7));

La sortie des deux premiers journaux n'est pas définie et TypeError: getSum n'est pas une fonction car var totalAmo et getSum sont hissés au sommet de leur portée comme ci-dessous

 <script>
        var totalAmo;
        var getSum;

        console.log(totalAmo);
        console.log(getSum(8,9));
        var totalAmo = 8;
        var getSum = function(a, b){
            return a+b;
        }
        console.log(totalAmo);
        console.log(getSum(9,7));
    </script>

Mais pour les fonctions de déclaration, des fonctions entières hissées au sommet de leur portée.

console.log(getId());
function getId(){
   return 739373;
}
/* output: 739373, because the whole function hoisted on the top of the scope.*/

Maintenant, la même logique s'applique aux varibales, aux expériences de fonctions et aux déclarations de fonctions déclarées dans la portée fonctionnelle. Point clé: ils ne seront pas hissés en haut du dossier ;

function functionScope(){
            var totalAmo;
            var getSum;

            console.log(totalAmo);
            console.log(getSum(8,9));
            var totalAmo = 8;
            var getSum = function(a, b){
                return a+b;
            }
        }

Ainsi, lorsque vous utilisez le mot clé var , la variable et la fonction hissées en haut de la portée (portée globale et portée de la fonction). Qu'en est-il de let et const , const et let sont toujours conscients de la portée globale et de la portée de la fonction, tout comme var l'est, mais les variables const et let sont également conscientes d'une autre portée appelée portée bloquée. une portée de bloc est présente chaque fois qu'il y a un bloc de code, comme une boucle for, une instruction if else, une boucle while, etc.

Lorsque nous utilisons const et laissons déclarer une variable dans la portée de ces blocs, seule la déclaration de variable sera hissée en haut du bloc dans lequel elle se trouve, et elle ne sera pas hissée en haut de la fonction parent ou en haut de la portée mondiale qu’elle est hissée.

 function getTotal(){
            let total=0;
            for(var i = 0; i<10; i++){
                let valueToAdd = i;
                var multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

Les variables de l'exemple abobe seront hissées comme ci-dessous

 function getTotal(){
            let total;
            var multiplier;
            total = 0;
            for(var i = 0; i<10; i++){
                let valueToAdd;
                valueToAdd = i;
                multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

0

ES5: fonction de levage et levage variable

function hoistingla priorité est greaterquevariable hoisting

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2016-06-01
 * @modified
 *
 * @description function-hoisting.js
 * @augments
 * @example
 * @link
 *
 */

(function() {
  const log = console.log;

  var a = 1;
  function b() {
    a = 10;
    log(`local a`, a)
    return;
    // function hoisting priority is greater than variable hoisting
    function a() {}
  }
  b();
  log(`global a`, a);
  // local a 10
  // global a 1
})();


qui est égal à

(function() {
  const log = console.log;

  // define "a" in global scope
  var a = 1;
  function b() {
    // define "a" in local scope
    var a ;
    // assign function to a
    a = function () {};
    // overwrites local variable "a"
    a = 10;
    log(`local a`, a);
    return;
  }

  b();
  // log global variable "a"
  log(`global a`, a);

  // local a 10
  // global a 1
})();

la raison derrière le levage

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined

/**
 *  scpope & closure & hoisting (var/function)
 *  
 * 1. scpope : the global var can be access in any place(the whole file scope), local var only can be accessed by the local scope(function/block scope)!
 * Note: if a local variable not using var keywords in a function, it will become a global variable!
 * 
 * 2. closure : a function inner the other function, which can access local scope(parent function) & global scope, howerver it's vars can't be accessed by others! unless, your return it as return value!
 * 
 * 3. hoisting : move all declare/undeclare vars/function to the scope top, than assign the value or null!
 * Note: it just move the declare, not move the value!
 * 
 */

ES6 let, constpas d'existence de levage

(() => {
  const log = console.log;
  log(a)
  // Error: Uncaught ReferenceError: Cannot access 'a' before initialization
  let a = 1;
})();


(() => {
  const log = console.log;
  log(b)
  // Error: Uncaught ReferenceError: Cannot access 'b' before initialization
  const b = 1;
})();

réfs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.