You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
30-Days-Of-JavaScript/js_notes/05-conditionals.js

204 lines
9.5 KiB

// 05 · 条件与布尔
// 学练复习一体:概念总结 → 示范 → 轮到你
// 跑法:Quokka / 右上角 ▷ / node 本文件
// 示范区带预期输出;轮到你区只给要求,自己写
// ═════ 概念总结 ═════
//
// 程序会"做决定"—— 根据条件走不同分支。这是代码从"一条直线"变成"有逻辑"的开始。
//
// 1. if / else if / else
// const age = 20
// if (age >= 18) {
// console.log('成年')
// } else if (age >= 13) {
// console.log('青少年')
// } else {
// console.log('儿童')
// }
// - 条件写在 () 里,结果要是 true/false(或真假值,见第 4 节)
// - {} 里是满足时执行的代码
// - 从上往下,命中第一个成立的就停,后面不再判断
//
// 2. 三元运算符 ? : ⭐
// if/else 的极简版,一行搞定"二选一",而且有返回值可以赋给变量:
// const status = age >= 18 ? '成年' : '未成年'
// // 条件 ? 真时的值 : 假时的值
// 适合:简单的二选一赋值。
// 别滥用:逻辑复杂就用 if,别把三元套三元,可读性差。
//
// 3. switch(多分支)
// 当一个值要和很多固定选项比对时,比一长串 else if 清爽:
// switch (day) {
// case 1:
// console.log('周一')
// break // ← 别忘!否则会"穿透"继续执行下面的 case
// case 3:
// console.log('周三')
// break
// default:
// console.log('其他')
// }
// 为什么每个 case 都要 break —— "穿透"(fall-through)⭐
// 关键:case 不是"独立的盒子",而是"跳转的入口(标签)"。匹配成功后程序从那个
// 入口跳进去,然后一路往下执行,撞到 break 才跳出。不写 break 就会"掉进"下一个 case。
// day = 1 时若各 case 都不写 break → 输出:周一 周二 周三(全跑了)
// 跨语言对比(纠正常见误解):
// ┌───────────────────────────┬──────────────────────────────────────┐
// │ 语言 │ 要 break 吗 │
// ├───────────────────────────┼──────────────────────────────────────┤
// │ C / C++ / Java / JS │ ✅ 都要(JS 的 switch 就是抄 C 的) │
// │ Python │ 没有传统 switch(match 机制不同,不穿透)│
// └───────────────────────────┴──────────────────────────────────────┘
// 记反了很常见:C++/Java 和 JS 一样都要写 break,不是自动 break。
// 穿透的唯一正当用法:多个 case 共用逻辑(故意省略 break):
// case 6:
// case 7:
// console.log('周末') // 6 和 7 都到这
// break
// 💡 因为"忘写 break"太容易出 bug,现代 JS 常少用 switch,改用 if/else if
// 或对象查表(学对象后会讲)。知道 switch 怎么回事即可,实战非首选。
//
// 4. 真假值 truthy / falsy ⭐⭐(之前埋的伏笔)
// if() 里不一定非要放 true/false —— 任何值都会被 JS 自动判成"真"或"假"。
// 假值(falsy)—— 只有这 6 个,记住就行:
// false 0 ''(空字符串) null undefined NaN
// 真值(truthy)—— 除了上面 6 个,其他全是真:
// 包括非零数字、非空字符串、[] 空数组、{} 空对象(注意!空数组空对象是真)
// if ('hello') … // 会执行
// if (0) … // 不执行
// if ([]) … // 会执行(容易错)
// 用途:快速判断"有没有值"(空串是假 → 走 else 分支)。
//
// 5. 短路:&& / || 返回的是"操作数原值",不是布尔 ⭐⭐
// 关键认知:JS 的 &&/|| 不返回 true/false,而是返回其中一个操作数本身。
// 靠的是短路求值:能确定结果时立刻停下,返回"决定胜负的那个值"。
// || :返回第一个真值(找到真就停);全假返回最后一个
// '' || '匿名' // '匿名' ← 前面假,继续,返回后面
// 'Tom' || '匿名' // 'Tom' ← 前面就是真,立刻返回,'匿名'看都不看
// 0 || 100 // 100
// && :返回第一个假值(找到假就停);全真返回最后一个
// 'Tom' && '有值' // '有值' ← 前面真,继续,返回后面
// '' && '有值' // '' ← 前面就是假,立刻返回它
// 1 && 2 && 3 // 3 ← 全真,返回最后一个
// 跨语言对比(纠正误解):
// ┌─────────────────────────────┬───────────────────────────────────┐
// │ 语言 │ &&/|| 返回 │
// ├─────────────────────────────┼───────────────────────────────────┤
// │ JS / Python / Ruby / Lua │ 操作数原值(如 '' || 'x' → 'x') │
// │ C / C++ / Java / C# │ 严格 boolean │
// └─────────────────────────────┴───────────────────────────────────┘
// 记反了很常见:Python 和 JS 一样返回原值;Java/C++ 才返回布尔。
// 两个超常用惯用法 ⭐:
// const name = userInput || '游客' // ① || 设默认值:没填(空串是假)就用 '游客'
// user && user.login() // ② && 做"守卫":user 存在才调用 login,避免报错
// // (React 里满地都是: 条件 && <组件/> → 条件成立才渲染)
// 想要纯布尔?用 !!:
// !!'Tom' // true !!'' // false !!0 // false
// ! 取反得布尔,!! 再反回来 → 纯 true/false。
// 💡 为什么这样设计:JS 到处用 truthy/falsy 而非死板布尔(见第 4 节),
// 所以 &&/|| 返回原值才顺理成章 —— 这两个知识点是一套的。
//
// ✅ 本主题要点回顾
// 1. if / else if / else:命中第一个成立的就停
// 2. 三元 条件 ? 真值 : 假值:简单二选一,有返回值 ⭐
// 3. switch:多分支,每个 case 别忘 break
// 4. falsy 只有 6 个:false 0 '' null undefined NaN;其余全 truthy(空数组空对象是真!)⭐⭐
// 5. &&/|| 返回操作数原值(非布尔):|| 取第一个真值(设默认值),&& 取第一个假值(做守卫);
// 要纯布尔用 !!。Python 同理,Java/C++ 才返回布尔 ⭐⭐
// ═════ 示范 ═════
// ── 1. if / else if / else ───────────────────────
const age = 20
if (age >= 18) {
console.log('成年') // ← 命中这个,输出:成年
} else if (age >= 13) {
console.log('青少年')
} else {
console.log('儿童')
}
// ── 2. 三元运算符 ? : ⭐ ──────────────────────────
const status = age >= 18 ? '成年' : '未成年'
console.log(status) // 成年
// ── 3. switch(每个 case 别忘 break)───────────────
const day = 3
switch (day) {
case 1:
console.log('周一')
break
case 3:
console.log('周三') // ← 输出:周三
break
default:
console.log('其他')
}
// ── 4. truthy / falsy ⭐⭐ ────────────────────────
// 假值只有 6 个:false 0 '' null undefined NaN
if ('hello') console.log('非空字符串 → 真') // 会执行
if (0) console.log('这行不会执行') // 0 是假
if ([]) console.log('空数组 → 真!') // 会执行(容易错)
if ('') {
console.log('空串是真')
} else {
console.log('空串是假 → 走这') // 会执行
}
// ── 5. 短路:|| 设默认值,&& 前真才看后 ⭐ ─────────
console.log('' || '匿名') // 匿名 ← 前面假,取后面
console.log('Tom' || '匿名') // Tom ← 前面真,直接取
console.log(true && '继续') // 继续
// ═════ 轮到你 ═════
// 👇 轮到你(只给要求,自己写代码)
// 练习 A:给一个 const score = 75
// 用 if/else if/else 判断等级并打印:
// >=90 打印 'A',>=60 打印 'B',否则打印 'C'
const score = 75
if (score >= 90) {
console.log('A')
} else if (score >= 60 ) {
console.log('B')
} else {
console.log('C')
}
// 练习 B:把练习 A 里"是否及格(>=60)"改用【三元运算符】写,
// 得到 '及格' 或 '不及格',打印出来
console.log(score >= 60 ? '及格' : '不及格')
// 练习 C(truthy/falsy):有 const username = ''
// 用 if 判断:如果 username 有值就打印它,否则打印 '游客'
// (想想空字符串是真还是假)
const username = ''
if (username) {
console.log(username)
} else {
console.log('游客')
}
// 练习 D(短路,动脑):用 || 把练习 C 改成【一行】,
// 效果一样:有名字用名字,没名字用 '游客'
console.log(username || '游客')
// 练习 E(挑战):写一个三元,判断 num 是奇数还是偶数,
// const num = 7,打印 '奇数' 或 '偶数'(回忆 % 取余)
const num = 7
console.log(num % 2 === 1 ? '奇数' : '偶数')
if (-3) {
console.log('true')
} else {
console.log('false')
}