【问题标题】:Javascript Lexical scopeJavascript 词法范围
【发布时间】:2023-04-01 09:56:01
【问题描述】:

我正在尝试理解词法范围的概念。据我所知,词法范围不能向后工作。在下面的 javascript 代码中,我在 scope3() 函数中声明了变量“名称”。但我试图在 scope1() 和 scope2() 函数中调用它。由于词法范围不能向后工作,我应该得到“名称未定义”,但它返回空字符串。有人可以解释一下吗?

var scope1 = function () {
  // name should have been undefined but its printing empty string
  console.log(name);
  var scope2 = function () {
    // name should have been undefined but its printing empty string
    console.log(name);
    var scope3 = function () {
      var name = 'Todd'; // locally scoped
    };
  };
  scope2();
};
scope1();

【问题讨论】:

  • 将您的代码包装在IIFE=> (function(){ /*your code*/ })() 中并查看结果。名称是全局window 对象的属性,因此您将获得""。在IIFE 中,使用var 定义的变量将引用局部变量..不是全局变量...
  • @RayonDabre 但是,覆盖默认(全局)属性是不好的做法。
  • 如果您适当地缩进,该代码将更容易理解。
  • 不,覆盖默认的全局属性是不错的做法。首先,他没有超越它。始终添加第二个新的全局属性。使用名为 name 的变量可能是在 i 旁边用于索引的最常见的 JavaScript 变量之一。

标签: javascript scope lexical-scope lexical-closures


【解决方案1】:

JavaScript 有 name 内置属性。因此,当您尝试获取 name 变量时,您将得到一个空字符串,因为它指向 window.name

你需要用别的东西代替名字。

【讨论】:

  • JavaScript 确实 not 有一个内置的 name 属性。 window 有一个 name 属性,但并非所有 JavaScript 环境都有一个 window 对象。例如,workers 和 node.js 都没有 window 对象。此外,他也不需要使用 name 以外的东西。他只需要明白它是从哪里来的。尝试使用不在 window 对象上的东西几乎是不可能的,因为每个新版本都会添加新东西。
【解决方案2】:

您需要对词法作用域有一个正确的理解,下面是一个简短而直接的例子来解释这个概念及其工作原理:

让我们说:

function(auto) {
   var vehicle = "bus";
   console.log(vehicle);

   function(innerAuto) {
     console.log(vehicle)
   }
   innerAuto();
}
auto();

因此,在此上下文中名为innerAuto 的内部函数获得了记录车辆值的指令,该值无处可寻,该函数立即知道它应该去外部范围查找它。即 JS 运行时已经知道,在执行此代码时,无需在 innerAuto 函数内部查看变量车辆的声明。所以你想知道它是怎么知道的?这是因为在编译期间它没有在innerAuto 函数中看到变量声明,而是在auto 函数中看到了它。所以词法范围只是编译时间范围。有关更多信息,请查看 MDN 文档,了解词法范围和闭包。

【讨论】:

    【解决方案3】:

    name 是依赖于实现的 JavaScript 对象的预定义名称列表的一部分。因此,它不会提供您期望的参考错误。将绑定 name 更改为 names 以查看预期的引用错误。

    您对词法作用域的逻辑理解也是绝对正确的。词法(或静态)范围,为函数(或块)提供查看其父函数(或块)的绑定。但是,父函数(或块)没有在其子函数中创建的绑定的视图。另一方面,全局绑定对所有人都是可见的。

    希望对你有帮助,谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多