# 通用概念 · 表达式(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 在显示"完成值",别当真。