【问题标题】:What is *actually* happening within this stale closure?在这个陈旧的闭包中*实际上*发生了什么?
【发布时间】:2022-01-23 07:55:39
【问题描述】:

我觉得我对闭包的了解几乎在那里,但我正在努力理解为什么第一个代码 sn-p 记录 0(是一个陈旧的闭包)但是,第二个代码sn-p 工作并记录更新的值..

这是某种参考问题吗?

在第一个例子中,我们是不是没有跟踪 count 的引用,只将它的初始值赋给 message?

通过在 log 函数中移动 message 变量,我们是否以某种方式告诉 JS 跟踪计数值的引用?

function createIncrement() {
  let count = 0;

  function increment() {
    count++;
  }

  let message = count;
  function log() {
    console.log(message);
  }

  return [increment, log];
}

const [increment, log] = createIncrement();

increment();
log();

// this will log 0

function createIncrement() {
  let count = 0;

  function increment() {
    count++;
  }

  function log() {
    let message = count;
    console.log(message);
  }

  return [increment, log];
}

const [increment, log] = createIncrement();

increment();
log();

// this will log 1

【问题讨论】:

  • "在第一个示例中,我们是否没有跟踪 count 的引用,而只将其初始值分配给 message?" - 是的。闭包跟踪message的引用,它只有count的初始值,但不会被log闭包更新。

标签: javascript closures


【解决方案1】:

在第一个例子中,我们是不是没有跟踪 count 的引用,而只是将它的初始值赋给 message?
通过在 log 函数中移动 message 变量,我们是否以某种方式告诉 JS 跟踪计数值的引用?

这就是你正在努力解决的问题。让我们尝试分解那里发生的事情。

它的核心就是这样:

let count = 0;
let message = count;
console.log(message);
count++; // it's exactly the same as count = count + 1;
console.log(message); // still prints 0

这与闭包无关,而与数字作为不可变值有关。当我们增加count 时,我们为变量分配了一个值为 1 的数字的新实例。 message 仍然指向旧实例(值,在这种情况下它是相同的),因此日志将打印相同的旧值。

如果我正确理解了您的误解(!),您认为count 是一个可以在其中插入数值的容器,这有点错误。

它是一个指向数字和不可变值的指针,它位于内存中的某个位置。当您执行 message = count 时,您确保 message 和 count 指向相同的内存地址,其中包含 0

当您编写count++ 时,您正在内存中某处为数字1 分配一个新数字,而count 现在指向新对象。 message 不受此操作的影响。 这是我认为不是很清楚的关键部分

在您的第二个示例中,message 在您每次登录时都会重新分配,因此它将始终包含对正确值的引用。

【讨论】:

  • 这正是我需要的,谢谢!
  • 我刚刚编辑了答案以更好地解释内存寻址。
猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-12
相关资源
最近更新 更多