在这个陈旧的闭包中*实际上*发生了啥?
Posted
技术标签:
【中文标题】在这个陈旧的闭包中*实际上*发生了啥?【英文标题】: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
闭包更新。
【参考方案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
在您每次登录时都会重新分配,因此它将始终包含对正确值的引用。
【讨论】:
这正是我需要的,谢谢! 我刚刚编辑了答案以更好地解释内存寻址。以上是关于在这个陈旧的闭包中*实际上*发生了啥?的主要内容,如果未能解决你的问题,请参考以下文章