console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10

====================

var a = 1;
if(true){
  function a(){};
  var a = 10;
}
console.log(a) // this code throws Uncaught SyntaxError: Identifier 'a' has already been declared

Les deux extraits de code ci-dessus sont identiques, sauf le bloc if.

 function a(){};
 var a = 10; //no error

Aussi pour un scénario légèrement différent après avoir supprimé var de `var a = 10 dans le code ci-dessus, alors cela fonctionne bien mais la sortie est surprenante

 var a = 1;
 if(true) {
   function a(){};
   a = 10;
 }
 console.log(a) //output:ƒ a(){}

Je suis surpris de voir cette sortie car j'attends 10 .. parce que deux variables déclarées à l'intérieur du bloc if font référence à la même variable déclarée ci-dessus car javascript var ne respecte pas la portée du bloc mais la portée fonctionnelle ... alors pourquoi pas la sortie pour ci-dessus devrait avoir 10 ans? où comme le code ci-dessous génère 10 comme prévu lors du remplacement de la définition de fonction par l'expression de fonction.

  var a = 1;
  if(true) {
    var a = function(){ console.log() }
    a = 10;
  }
  console.log(a) //output:10
14
venkata 11 avril 2018 à 15:09

3 réponses

Meilleure réponse

Cela est surprenant car javascript var ne respecte pas la portée du bloc mais la portée fonctionnelle ...

Bien sûr, mais vous n'avez pas utilisé var pour la déclaration de a dans la portée du bloc. Vous avez utilisé une déclaration de fonction, qui ne respecte pas les étendues de bloc (sinon ce serait code complètement invalide, comme en mode strict ES5).

Il est permis en javascript de déclarer deux fois la même variable dans la même portée avec var comme ci-dessous

Il en va de même ici. La déclaration function du bloc utilise la sémantique de déclaration ES6 (comme let ou const), qui n'autorise pas les redéclarations.

9
Bergi 11 avril 2018 à 12:42

Cas 1

console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10

Sera rendu comme

var a;
a = function(){}; // now a holds the value as a function
console.log(a); // output : f a(){}
a = 1; // a is a var that holds value 1
a = 10; // a is a var that holds value 10
console.log(a); // output : 10

Cas 2

var a = 1;
if(true){
   function a(){};
   var a = 10;
}
console.log(a)

Sera rendu comme

var a;
a = 1;
if(true) {
    a = function() {};
    let a; // The function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow re-declarations.
    var a; // throws Uncaught SyntaxError: Identifier 'a' has already been declared
    a = 10;
}
console.log(a);

Cas 3

var a = 1;
if(true){
    function a(){};
    a = 10;
 }
console.log(a)

Sera rendu comme

var a;
a = 1;
if(true) {
    a = function() {};
    let a;
    a = 10;
}
console.log(a); // output : f a(){}

Cas 4

var a = 1;
if(true){
    var a= function(){console.log()}
    a = 10;
}
console.log(a)

Sera rendu comme

var a;
a = 1;
if(true) {
    a = function(){console.log()}
    a = 10;
}
console.log(a) // output:10

Cas 5

var a = 1;
if(true){
    function a(){};
    a = 10;
    console.log(a) 
}
console.log(a) 

Sera rendu comme

var a;
a = 1;
if(true){
    a = function() {};
    let a;
    a = 10;
    console.log(a); // output:10
}
console.log(a); // output : f a(){}
4
Nikhil Aggarwal 12 avril 2018 à 08:43

La solution simple à cela consiste à utiliser IIFE

(function() {
var sahil = {
  checkThis: function() {
    console.log(this);

    function checkOther() {
      console.log(this);
    }
    checkOther(); // checkThis() function called in "global context", will
                  // return "this" as "window"
  }
};
var moo = sahil.checkThis;
moo(); // moo() function called in "global context", will return "this" as "window" })();
0
Nick 7 janv. 2019 à 03:28