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

时间:2018-04-11 12:09:24

标签: javascript scope var hoisting

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块。为什么后者在javascript中允许delcare同一个变量两次在同一范围内使用var,如下所示抛出错误

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

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

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

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

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

3 个答案:

答案 0 :(得分:4)

  

这是令人惊讶的,因为javascript var并不尊重块范围,但功能范围......

当然,但您没有在块范围内使用var来声明a。您使用了函数声明does respect block scopes(否则它将是completely invalid code,与ES5严格模式一样)。

  

允许在javascript中使用var在同一范围内两次声明相同的变量,如下所示

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

答案 1 :(得分:4)

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

案例3

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

答案 2 :(得分:0)

对此的简单解决方案是使用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" })();