【问题标题】:Why doesn't the outer scope variable get properly bound to the inner variable?为什么外部范围变量没有正确绑定到内部变量?
【发布时间】:2014-06-16 12:06:37
【问题描述】:
(function(){
  var x = 23;
  return function(){
    var x = x;
    return x;
  }
}())();

为什么它返回 undefined 而不是 23?

不应该是 var x = x;部分是否足够明确,因为右侧隐含地引用外部范围内的 x?

【问题讨论】:

  • 我认为这可能与变量的提升有关:变量是声明然后赋值的,所以右侧x与左侧相同
  • 不,因为您返回的函数直到 x 的初始声明范围消失后才会执行。因此,当您执行它时它是未定义的。您应该将x 传递给您的return function
  • 你不需要var x = x;
  • @RGraham 我认为这不是原因,因为(function(){ var y = 23; return function(){ var x = y; return x; }}())(); 有效
  • @Pablo,RobG 谢谢,现在就搞定。

标签: javascript scope


【解决方案1】:

语句var x = x; 没有从外部范围看到变量x。作用域内的变量x在赋值之前就已经存在,并且从外部作用域中隐藏了变量。

作用域中的所有变量都是在作用域中的代码执行(提升)之前创建的,所以它就像你有一样:

(function(){
  var x;
  x = 23;
  return function(){
    var x;
    x = x;
    return x;
  }
}())();

实际上,在范围内声明变量的位置并不重要。您可以在代码中最后声明它们(尽管这会有点混乱),并且代码仍然可以正常工作:

(function(){
  x = 23;
  return function(){
    x = x;
    return x;
    var x;
  }
  var x;
}())();

【讨论】:

  • 谢谢你的解释。不过,我不明白这种行为有什么意义。
  • @user3280015:如果不是这样,您会遇到一些不一致的情况。例如,在循环中,变量可能在第一次迭代时表示一件事,在下一次迭代时表示另一件事。
  • @user3280015:它可能适用于某些语言(有很多),但最常用的语言对变量有某种范围,这意味着赋值看不到变量从外部范围。
【解决方案2】:

不应该是 var x = x;部分是否足够明确,因为右侧隐含地引用外部范围内的 x?

没有。变量的所有作用域都是在执行任何赋值之前确定的。

【讨论】:

  • 语言规范没有解释为什么要这样设计。 (OTOH,我不明白为什么允许两个不同的变量在一个范围内的不同时间具有相同的名称是个好主意)。
  • 昆汀,这将是两个不同的变量在两个不同的范围内具有相同的名称。我可以想象几个用例。
【解决方案3】:

有一个叫做变量提升的概念。简而言之,在执行函数之前,所有在函数内部声明的变量都将被标记为未定义。所以它返回未定义..由于变量提升,您可以稍后定义变量但可以在之前使用它..例如。 function(){alert(x);var x;} 会提醒 undefined 但function(){alert(x);} 会抛出错误..

【讨论】:

    【解决方案4】:

    给定:

    (function(){
      var x = 23;
      return function(){
        var x = x;
        return x;
      }
    }())();
    

    内部函数只看到内部x

    当进入执行上下文时,所有声明的变量都会被初始化,给定值undefined,并在执行任何代码(例如赋值)之前放置在一种变量对象上。所有外部变量都放在作用域链上。

    解析标识符时,首先检查变量对象,只有在没有找到时才检查作用域链。

    【讨论】:

      猜你喜欢
      • 2021-08-18
      • 2016-03-14
      • 2019-10-05
      • 2017-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      相关资源
      最近更新 更多