From f672004c372d01a318d931f1405cf467a621a794 Mon Sep 17 00:00:00 2001 From: Jaydon Date: Sat, 25 Jul 2026 06:13:09 +0800 Subject: [PATCH] docs(js_notes): add expression-vs-statement concept note - new 00-concepts note: which has a value / can be used as a value; the REPL 'completion value' illusion; ties together arrow =>, ternary, return - README: index it under cross-topic concepts --- .../00-concepts/expression-vs-statement.md | 53 +++++++++++++++++++ js_notes/README.md | 1 + 2 files changed, 54 insertions(+) create mode 100644 js_notes/00-concepts/expression-vs-statement.md diff --git a/js_notes/00-concepts/expression-vs-statement.md b/js_notes/00-concepts/expression-vs-statement.md new file mode 100644 index 0000000..88b5cec --- /dev/null +++ b/js_notes/00-concepts/expression-vs-statement.md @@ -0,0 +1,53 @@ +# 通用概念 · 表达式(expression) vs 语句(statement)⭐ + +> 跨主题核心区分。它决定"这东西能不能当值用",串起箭头函数、return、三元、if。 +> 相关:`../10-functions.js` §2(箭头 => 期待表达式)、`../05-conditionals.js`(三元 vs if)。 + +## 一句话分界 + +- **表达式 = 能算出一个【值】的东西** → 有值,能赋给变量、能当参数传。 +- **语句 = 执行一个【动作】的东西** → 在你的代码里【没有值】,不能当值用。 + +判断诀窍:**能不能塞进 `=` 右边(或当函数参数)?能 = 表达式;塞进去报 SyntaxError = 语句。** + +## 谁是表达式,谁是语句 + +| 表达式(有值) | 语句(没值) | +|---|---| +| `1 + 2`、`n * 2` | `if (...) {...}` | +| `'hi'`、`` `${x}` `` | `for / while (...) {...}` | +| `x = 99`(赋值也是表达式!值是 99) | `let x = 1` / `const y = 2`(声明) | +| `5 > 3 ? 'a' : 'b'`(三元) | `return x` / `break` / `continue` | +| `fn(1, 2)`(函数调用) | `function f(){}`(函数声明) | + +```js +const a = 1 + 2 // ✅ 1+2 是表达式,有值 3 +const b = if (true) { 1 } // ❌ SyntaxError:if 是语句,没有值,不能赋 +const m = 5 > 3 ? 'a' : 'b' // ✅ 三元是表达式;换成 if 就不行 → 这就是三元存在的意义 +``` + +## ⚠️ 最容易被骗的地方:控制台里"语句好像有值" + +在浏览器 F12 控制台 / `eval` 里敲一句 `if (true) { 5 }`,回车会显示 `5`,看着"像有返回值": + +```js +eval('if (true) { 5 }') // 5 ← 底层的"完成值(completion value)" +eval('let z = 1') // undefined +const bad = if (true) {5} // ❌ SyntaxError:想把它捞进变量,立刻现原形 +``` + +真相:语句在**引擎底层**确实有个"完成值",但**你在正常代码里拿不到**,只有 +`eval` 和 REPL(控制台)会把它显示出来。**别被控制台的显示骗成"语句能当值用"。** + +## 为什么这个区分重要(它串起好几个点)⭐ + +- **箭头函数**:`=>` 右边【期待表达式】。所以 `(a,b) => a+b` ✅(a+b 是表达式); + `(a,b) => return a+b` ❌ SyntaxError —— 因为 `return` 是【语句】,没有值,不能放这。 +- **三元 vs if**:三元是表达式(能 `const x = 条件 ? a : b`),if 是语句(不能赋值)。 + 需要"按条件得到一个值"时用三元,正因为它有值。 +- **隐式返回**:箭头后给表达式 → 它就是值 → 自动返回;给 `{语句块}` → 块没值 → 得手写 return。 + +## ✅ 一句话记死 + +> **表达式有值、能当值用(赋值/传参);语句是动作、在代码里没值(塞进 `=` 右边就 SyntaxError)。** +> 控制台里语句"显示出一个值"是 REPL 在显示"完成值",别当真。 diff --git a/js_notes/README.md b/js_notes/README.md index 76a06b7..d5fb55e 100644 --- a/js_notes/README.md +++ b/js_notes/README.md @@ -40,6 +40,7 @@ - `00-concepts/value-vs-reference.md` —— 值 vs 引用:复制 vs 共享、字符串不可变 ⭐ - `00-concepts/shortcircuit-bash-vs-js.md` —— `&&`/`||`:bash vs JS(`0` 真假相反) - `00-concepts/semicolons-and-asi.md` —— 分号 `;` 什么时候【必须】写(ASI 的坑:行首 `(`/`[`、`return` 换行)⭐ +- `00-concepts/expression-vs-statement.md` —— 表达式 vs 语句:谁有值/能当值用(串起箭头 `=>`、三元、return)⭐ ### 一、基础与数据 - [x] `01-basics` 基础:输出、注释、表达式、字符串引号、运行方式