javascript-未捕获的SyntaxError:标识符*已经声明

ven*_*ata 7 javascript scope var hoisting

console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
Run Code Online (Sandbox Code Playgroud)

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

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

除了if块之外,上面两个代码片段是相同的.为什么后者在javascript中允许delcare同一个变量两次在同一范围内使用var,如下所示抛出错误

 function a(){};
 var a = 10; //no error
Run Code Online (Sandbox Code Playgroud)

同样对于在上面的代码中从var变量= 10中删除var之后略有不同的情况,那么它工作正常但输出却令人惊讶

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

我很惊讶地看到这个输出,因为我期待10 ..因为在if块内声明的两个变量引用上面声明的相同变量javascript var不尊重块范围但功能范围...所以为什么不输出上面应该10点?当用函数表达式替换函数定义时,下面的代码输出10,就像我预期的那样.

  var a = 1;
  if(true) {
    var a = function(){ console.log() }
    a = 10;
  }
  console.log(a) //output:10
Run Code Online (Sandbox Code Playgroud)

Nik*_*wal 10

情况1

console.log(a) //output:ƒ a(){}
var a = 1;
function a(){};
var a = 10;
console.log(a) //output:10
Run Code Online (Sandbox Code Playgroud)

将呈现为

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
Run Code Online (Sandbox Code Playgroud)

案例二

var a = 1;
if(true){
   function a(){};
   var a = 10;
}
console.log(a)
Run Code Online (Sandbox Code Playgroud)

将呈现为

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);
Run Code Online (Sandbox Code Playgroud)

案例3

var a = 1;
if(true){
    function a(){};
    a = 10;
 }
console.log(a)
Run Code Online (Sandbox Code Playgroud)

将呈现为

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

案例四

var a = 1;
if(true){
    var a= function(){console.log()}
    a = 10;
}
console.log(a)
Run Code Online (Sandbox Code Playgroud)

将呈现为

var a;
a = 1;
if(true) {
    a = function(){console.log()}
    a = 10;
}
console.log(a) // output:10
Run Code Online (Sandbox Code Playgroud)

案例5

var a = 1;
if(true){
    function a(){};
    a = 10;
    console.log(a) 
}
console.log(a) 
Run Code Online (Sandbox Code Playgroud)

将呈现为

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


Ber*_*rgi 6

这是令人惊讶的,因为javascript var不遵守块范围而是功能范围...

可以,但是您没有在块作用域中var用于的声明a。您使用了一个函数声明,该声明确实遵守块作用域(否则,它将完全是无效的代码,如在ES5严格模式下一样)。

在javascript中,可以在同一范围内两次声明相同的变量var,如下所示

此处同样适用。function块中的声明使用ES6声明语义(如letconst),不允许重新声明。


小智 5

解决这个问题的简单方法是使用 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" })();
Run Code Online (Sandbox Code Playgroud)