【问题标题】:In Javascript, can a closure share scope with a function return value?在 Javascript 中,闭包可以与函数返回值共享范围吗?
【发布时间】:2022-01-25 14:10:59
【问题描述】:

我试图从 Eloquent Javascript 中理解这段无法解释的代码:

function trackKeys(keys) {
  let down = Object.create(null);
  function track(event) {
    if (keys.includes(event.key)) {
      down[event.key] = event.type == "keydown";
      event.preventDefault();
    }
  }
  window.addEventListener("keydown", track);
  window.addEventListener("keyup", track);
  return down;
}

var arrowKeys =
  trackKeys(["ArrowLeft", "ArrowRight", "ArrowUp"]);

我想我理解内部函数track 将如何保持对downkeys 的引用,因为它是一个闭包,但我迷失在return down;

该返回值是否会引用回调正在访问的完全相同的down?我不明白;我以为局部变量只能被内部函数访问?

跟进:如果 down 是原始数据类型而不是对象,这仍然有效吗?

【问题讨论】:

    标签: javascript scope closures


    【解决方案1】:

    函数将变量down初始化为对象。

    所以在函数内部,down 是一个指向某个对象的变量。

    当函数返回down时,它返回一个对对象的引用,这意味着该对象可以通过函数的返回来访问。

    如果down 是原始的,那么这将不起作用,因为该函数只会返回原始值而不是对对象的引用。

    【讨论】:

      【解决方案2】:

      TLDR: 由于人类语言固有的不精确性,说“返回一个变量”是模棱两可的。这并不意味着返回标识符和值的变量对。这意味着返回变量的。在这种情况下,将返回对对象(由Object.create(null) 创建)的引用值。

      该返回值是否会引用完全相同的down 回调正在访问?

      是的。

      我认为局部变量只能由内部函数访问?

      变量是标识符(即变量的名称)和值的配对。

      范围是标识符(在本例中为“down”)具有特定含义的代码区域。

      标识符的范围由声明变量的方式决定(const/let/var/非严格模式下的隐式)。变量down 使用let 声明;因此它的作用域是最近的包含块,即函数trackKeys

      trackKeys 中声明的函数将通过JavaScript 内置的闭包形成机制关闭down,因此将共享标识符“down”的含义。

      注意:如果内部函数或块声明了自己的名为"down"的变量,这些内部变量将导致错误(var在严格模式下的非功能块中,重复声明),什么都不做(var 在非功能块中的非严格模式下),或隐藏(隐藏)外部变量(let/const)。

      返回 down 不会更改标识符 down 的范围。尝试在 trackKeys 之外引用“down”将继续出错或返回 undefined,具体取决于您是否处于严格模式。但是,返回 down 的值确实会使该值在 trackKeys 之外可用。

      【讨论】:

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