【问题标题】:javascript- Uncaught SyntaxError: Identifier * has already been declaredjavascript- Uncaught SyntaxError: Identifier * has already been declared
【发布时间】:2018-09-21 07:42:10
【问题描述】:
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

上面的代码 sn-ps 都是相同的,除了 if 块。为什么后者在 javascript 中允许在同一范围内使用 var 两次删除相同变量时抛出错误,如下所示

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

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

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

【问题讨论】:

标签: javascript scope var hoisting


【解决方案1】:

这令人惊讶,因为 javascript var 不尊重块作用域而是函数作用域......

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 在案例 3 中更像 let a
    • @Bergi - 谢谢。我在发表我的理解时参考了您的回答。希望你没事。如果没有,我很乐意删除我的答案。
    • @PrashantTapase - 谢谢。为了更好地理解,我更新了我的答案,您现在也可以看到错误陈述的行为。
    • @nikhilagw 没关系 :-)
    • 现在很清楚了。非常感谢nikhilagw。谢谢@Bergi
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2019-07-23
      • 2021-03-23
      • 1970-01-01
      • 2017-10-13
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      相关资源
      最近更新 更多