web-dev-qa-db-ja.com

javascript-キャッチされていないSyntaxError:識別子*はすでに宣言されています

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

上記の両方のコードスニペットは、if block.whyがエラーをスローすることを除いて同じですが、JavaScriptで以下のようにvarを使用して同じスコープ内で同じ変数を2回Delcareできる場合にエラーがスローされます

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

また、上記のコードで `var a = 10からvarを削除した後の少し異なるシナリオでは、正常に機能しますが、出力は意外です

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

If内で宣言された2つの変数が、javascript varはブロックのスコープではなく機能のスコープを尊重するので、上記で宣言された同じ変数を参照するため、この出力を見て驚いています。 10歳?ここで、以下のコードは、関数定義を関数式に置き換えたときに期待どおりに10を出力します。

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

Javascript varはブロックスコープを考慮せず、機能スコープを考慮しているため、これは驚くべきことです...

もちろん、ブロックスコープのvarの宣言にaを使用していません。 doesがブロックスコープを尊重する関数宣言を使用しました (それ以外の場合は ES5 strictモードのように、完全に無効なコード )。

以下のようにvarを使用して、同じスコープ内で同じ変数を2回宣言することは、JavaScriptでは許可されています。

ここでも同じことが言えます。ブロック内のfunction宣言はES6宣言セマンティクス(letまたはconstなど)を使用しているため、再宣言はできません。

3
Bergi

ケース1

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

としてレンダリングされます

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

ケース2

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

としてレンダリングされます

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);

ケース

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

としてレンダリングされます

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

ケース4

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

としてレンダリングされます

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

ケース5

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

としてレンダリングされます

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

これに対する簡単な解決策は、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