web-dev-qa-db-fra.com

javascript- Uncaught SyntaxError: l'identifiant * a déjà été déclaré

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, à l'exception du bloc if.why, pourquoi ce dernier génère-t-il une erreur lorsque son code javascript est autorisé à supprimer deux fois la même variable dans le même champ d'application avec var comme ci-dessous

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

Également pour un scénario légèrement différent après la suppression de 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 je m'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 comme javascript var ne respecte pas la portée du bloc, mais la portée fonctionnelle ... alors pourquoi ne pas la sortie ci-dessus devrait be 10? Où, comme le code ci-dessous, 10 comme prévu lorsque la définition de la fonction a été remplacée par l'expression de la fonction.

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

Ceci 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 fait respecte les étendues de bloc (sinon ce serait code totalement invalide , comme en mode strict ES5).

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

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

3
Bergi

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(){}

Affaire 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(){}
3
Nikhil Aggarwal

La solution simple à cela est d'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
Mohd Sahil