JS 执行机制,其实也没那么复杂 ——拿日常来打打比方你就懂了

引言

你有没有过这样的经历?

  • 写代码时变量找不到,不知道为什么;
  • 函数调用顺序乱七八糟,自己都搞不清谁先谁后;
  • 看到"闭包"两个字就头大,感觉根本不明白。

别担心,这些看似高深的概念,其实都能用我们生活中常见的场景来类比。今天我们就用"日常逻辑"来聊聊 JS 是怎么运行你的代码的。


🧑‍💼 调用栈:JS 的"任务清单"

想象一下你是个上班族,每天早上打开电脑的第一件事就是列个待办事项清单:

  1. 回复邮件 ✅
  2. 开会 ⏳
  3. 写报告 📝

这个清单就是你的 调用栈(Call Stack) ,它是 JS 用来管理函数调用顺序的一个"任务清单"。

比如:

lua 复制代码
function 做早餐() {
  console.log("煎蛋");
}
function 上班() {
  console.log("开会");
  做早餐();
}
上班();

JS 的调用栈是这样工作的:

  • 先执行 上班() → 把它放进任务清单;
  • 发现里面要执行 做早餐() → 把它压进去;
  • 做早餐() 完成后弹出;
  • 最后 上班() 完成也弹出。

就像你先开始上班流程,中途临时去煎了个蛋,吃完再回来继续上班。


🏡 作用域:你家的门禁

你可以把每个函数看作是一个房间,房间里有私人物品(变量),不是谁都能随便拿。

javascript 复制代码
function 房间A() {
  let 杯子 = "在床头";
}
function 房间B() {
  console.log(杯子); // ❌ 找不到!
}

这就是 作用域(Scope) :决定一个变量在哪里能被访问。

作用域链:找东西从近到远

如果你在一个房间里找遥控器,你会怎么做?

  • 先在自己房间找;
  • 没找到,去室友房间看看;
  • 还没有,就去客厅(全局空间)翻一翻。

JS 查找变量也是这样:

javascript 复制代码
let 零花钱 = 50;

function 外层() {
  let 存款 = 10000;
  function 内层() {
    let 收入 = 8000;
    console.log(零花钱); // 找到了!去外层找
  }
  内层();
}
外层();

这个查找路径就叫做 作用域链(Scope Chain)


🧱 词法作用域:你出生在哪,决定了你能看到什么

这个词听起来很专业,但其实很好理解:

你在哪写的函数,它能看到哪些变量,就已经定下来了。

举个例子:

javascript 复制代码
let 地点 = "兴国";

function 打印地点() {
  console.log(地点);
}

function 外层() {
  let 地点 = "抚州";
  打印地点(); // 输出的是兴国,不是抚州!
}

虽然 打印地点() 是在"外层"里被调用的,但它是在全局作用域中被定义的,所以它看到的还是"兴国"。

就像你出生在兴国,不管以后搬到哪生活,身份证上的籍贯是不会变的。


🎁 闭包:记住你曾经拥有的一切

终于说到"闭包"了。这可是很多人觉得最难懂的部分,但我们用隔壁老张的故事来解释它。

故事:

你一直记得一个女孩,你们曾经在一起三年,很相爱,一起经历过很多事,开心,难过,距离,矛盾。可是后来你们分开了,再也没有续集了,但你一直记得那个女孩。 直到有一天你去到你们常去的酒馆,你恍惚了,想知道她还在吗,可是她已经不在了,可是只要你还记得她,她就一直在你心里,这个她,就是闭包里的变量。

看代码:

javascript 复制代码
function 创建女孩() {
  let 回忆 = ["散步", "喝酒"];
  return function () {
    console.log(回忆);
  };
}

let 记忆 = 创建女孩();
记忆(); // 输出: ["散步", "喝酒"]

即使 创建女孩() 已经执行完了,里面的变量 回忆 并没有被销毁,因为还有一个函数(闭包)还记着它。

💡 闭包的本质:函数 + 它能记住的词法作用域


🔚 总结一句话:

JavaScript 的执行机制,就像你的生活:

  • 调用栈 是你的待办清单;
  • 作用域 是你家的门禁系统;
  • 作用域链 是你找东西的路线图;
  • 词法作用域 决定了你"出生地"的归属感;
  • 闭包 就是隔壁老张永远记得的那个她。

理解了这些,你就不再只是写代码的人,而是真正懂得代码为什么会这样运行的开发者啦!


相关推荐
Goboy24 分钟前
用 PyQt5 打造一个可视化 JSON 数据解析工具
ai编程·trae
Goboy30 分钟前
《我养的修仙 AI 会渡劫》:我用 Trae 把它“说”出来了
ai编程·mcp·trae
Favorite_Ystar1 小时前
了解Function Calling的原理
trae
cpp加油站1 小时前
来了,Trae的国内竞争对手Lingma出现了,盘点国产AI 原生IDE现状
ai编程·trae
逍遥101 小时前
MacOS下Qt+qml+Android开发系列:2、切换页面
android·qt·trae
这里有鱼汤1 小时前
如何把MCP和DeepSeek大模型融合,让AI了解实时股票行情
后端·python·trae
ReturnOfMars1 天前
字节Trae 接入MCP实战
trae
二进制独立开发2 天前
[Trae 1.4.0+] Trae Flask的智能体发布
flask·trae
围巾哥萧尘2 天前
「网站制作」Lovart 原型,Trae 网站,掘金 MCP部署🧣
trae