JavaScript的秘密生活:回忆

发布: (2026年1月6日 GMT+8 04:40)
6 min read
原文: Dev.to

Source: Dev.to

鬼屋:闭包与不肯消亡的变量的故事

Timothy 站在主图书馆走廊旁一个小型私人书房的门口。他刚刚在里面完成了一项任务——计算一个特定的数字,并把结果 42 写在一张纸条上。

他把纸条放在桌子上,走出走廊,牢牢地把门关上。

“好了,任务完成了,” Timothy 边说边抖掉外套上的灰尘。“函数已经运行结束。清洁工随时会来把房间打扫干净。”

Margaret 站在旁边,腰带上挂着一串钥匙,轻轻摇了摇头。“你确定房间会被打扫干净吗,Timothy?”

“当然,” 他回答道。“这就是 Garbage Collector 的规则。当函数结束时,它的局部变量——栈帧——会被销毁。内存被释放,房间变暗。”

Margaret 笑了,眼中闪过一丝调皮的光芒。“通常是这样。不过告诉我……你有没有把什么东西带出房间?”

The Souvenir (The Inner Function)

Timothy 检查了口袋。“嗯,我没有带数字本身。但我带了这个。”

他举起一把小小的黄铜钥匙。钥匙上挂着一个标签,上面写着 getSecret()

“我在房间内部创建了这把钥匙,”Timothy 解释道。“它可以让我——或者任何持有它的人——回到房间里,读取我写在桌子上的数字。”

“正是如此,”Margaret 低声说。“你从一个 Function 中返回了另一个 Function。”

她指向书房的门。Timothy 本以为灯会熄灭,房间会空无一人。相反,门框下仍有微弱的幽光在闪烁。

“因为你持有那把钥匙,”Margaret 说,“清洁工无法打扫这个房间。只要这把钥匙在外部世界存在,房间——以及里面的一切——就必须保持时间冻结。Timothy,这就是一个 Closure。”

背包(词法作用域)

“我原以为函数只是指令,” Timothy说,望着那把黄铜钥匙。“我没想到它们还能携带行李。”

“它们携带自己的出生地,” Margaret纠正道。“当一个函数诞生时,它会对周围的世界进行快照。它记得自己的来源。它背着一个装满看不见的线索的背包,这些线索连接到它创建时所存在的每个变量。”

“所以即使外层函数——‘Study’——已经结束了?”

“Study对公众已关闭,” Margaret点头同意。“但对来说,握着那把钥匙,Study仍然是打开的。变量 42 并未消亡。它被记住了。”

代码(机器中的幽灵)

Timothy 好奇地冲向绘图台。他需要在脚本本身中验证这种幽灵般的持久性。

function createStudy() {
    // The Local Variable (The Note on the Desk)
    const secret = 42;

    // The Inner Function (The Key)
    // It captures the 'secret' variable from its birthplace
    return function getSecret() {
        console.log("The secret is:", secret);
    };
}

// 1. Run the function. The "Study" opens and closes.
const myKey = createStudy();

// At this point, createStudy() has finished.
// The variable 'secret' should be gone (Garbage Collected).

// 2. But we try to use the key later...
myKey();
// Output:
// The secret is: 42

Timothy 注视着控制台输出。

“它活了下来,” Timothy 喘息道。 “createStudy 函数早已执行完毕。但 myKey 仍然记得 secret。”

私有数据(封装)

“这是一种强大的魔法,” Timothy意识到。“如果我把这把钥匙交给陌生人,他们可以读取秘密。但他们不能更改它,对吗?”

“看看你的代码,” Margaret说。“你给了他们一个在桌子上的钥匙吗?”

“没有。只有一个读取它的函数。”

“那数据就是安全的,” Margaret点头说。“你已经创建了Private State。变量被锁在闭包内部,免受全局作用域的混乱。这是数据隐私、模块和安全的基础。”

Timothy最后一次看了看发光的门口。它不是闹鬼的;它是安全的。

“它不是鬼,”他纠正自己。“它是一个Backpack。每个函数都携带着它所属环境的记忆。”

“正是如此,” Margaret说,转身离开。“这就是我们永远不会真正忘记来处的原因。”

Back to Blog

相关文章

阅读更多 »