4.1 语言基础:变量、类型与流程控制


4.1 语言基础:变量、类型与流程控制

本节摘要:变量用声明关键字开设储物格,值分基本类型与对象两大类,赋值时"拷贝值"与"拷贝引用"的差异是新手第一大坑;比较运算分宽松与严格;分支与循环组织代码的走向。本节用一段工单优先级判定的脚本把这些语法串成完整逻辑,为整章搭好语言地基。

班前进课:变量是贴了标签的储物格

行为班开工前先认工具。变量是内存里贴了标签的储物格:声明就是开格贴标签,赋值就是往格里放东西。声明关键字有三个,现代代码只用后两个:老关键字作用域古怪(变量提升会在声明前就让它存在),块级声明的花括号作用域符合直觉;不可重新赋值的声明用于不会变的绑定,具有自文档化的效果——读到它就知道这个值不该被改。

// 三种声明与命名约定 let orderCount = 0; // 可变绑定:工单计数,会随登记增长 const WORKSHOP = "三车间"; // 不可变绑定:车间名不会变,全大写提示常量气质 // var orderNo = 1; // 老关键字:作用域古怪,新代码不再使用 orderCount = orderCount + 1; // 可变绑定重新赋值:合法 // WORKSHOP = "二车间"; // 不可变绑定重新赋值:直接报错,错误暴露得越早越好 // 命名约定:小驼峰,动词开头表示函数、名词表示数据 let pendingCount = 0; function countPending() { return pendingCount; }
// 值与引用:赋值行为的分水岭 let a = 42; let b = a; // 基本类型:拷贝值——b 拿到 42 的副本 b = 99; // 改 b 不影响 a(a 仍是 42) let orderA = { product: "凸轮轴" }; let orderB = orderA; // 对象:拷贝引用——两标签指向同一只箱子 orderB.product = "导套"; console.log(orderA.product); // "导套":改一处,处处变

第二个代码块是新手第一大坑的现场:基本类型(数字、字符串、布尔、空值、未定义、符号、大整数)赋值拷贝内容,对象(含数组与函数)赋值拷贝的是"箱子地址"。两个标签指向同一只箱子时,谁都能往里改东西——数据莫名变化的故障,八成源头在此。

类型判断与比较的松紧

类型判断首选类型关键字运算符,它直接回答"这个值是什么类型"。比较运算分两套:宽松相等会先做类型转换再比(空串与数字零相等这种反直觉结果由此而来),严格相等类型不同直接判不等。工程纪律只有一条:一律用严格相等,让类型转换发生在你显式书写的地方。

// 类型与比较的实操 const input = "12"; // 表单拿到的永远是字符串 console.log(typeof input); // "string":类型关键字给出类型名 console.log(input === 12); // 假:字符串与数字类型不同,严格相等判不等 console.log(input == 12); // 真:宽松相等偷偷转了类型——隐患之源 const num = Number(input); // 显式转换:字符串转数字,转换点清清楚楚 console.log(num === 12); // 真:转换后严格比较,结果可预期 // 空值的两副面孔 let notAssigned; // 声明未赋值 console.log(notAssigned); // undefined:还没放东西 console.log(null === notAssigned); // 假:null 是"刻意放了个空",undefined 是"根本没放"
// 表单输入处理的严格套路 function parseOrderNo(raw) { const trimmed = raw.trim(); // 去掉首尾空格 if (trimmed === "") return null; // 空串:明确返回 null 表示"无值" const no = Number(trimmed); if (Number.isNaN(no)) return null; // 转不出数字:同样返回 null return no; } // 套路要点:先清洗、再判空、再转换、再验转换结果 // 每一步都可能失败,每步失败都有明确出口

分支与循环:代码的岔路和传送带

分支组织"什么条件下走哪条路",循环组织"什么范围内重复做"。现代语法里两者都有轻量版:多路分支的简洁写法适合枚举取值判断,遍历容器首选"取每一项"的循环写法——不用自己管下标,边界错误从根上消失。

// 工单优先级判定:分支的完整版与轻量版 function slaOf(priority, status) { if (priority === "urgent" && status === "pending") { return "立刻排产,三十分钟内必须开机"; // 双条件同时成立 } else if (priority === "urgent") { return "加急在制,每小时巡检一次"; } else if (status === "done") { return "已完工,归档前复检"; } return "常规节奏,按计划走"; // 兜底分支必须有 } const label = { pending: "待开工", running: "加工中", done: "已完成" }; const text = label[status] ?? "未知状态"; // 查表代替连串分支:枚举判断优先查表,代码量与分支数同减 // 空值合并:查不到给默认值,比逻辑或更精准(零和空串不会被误替换)
// 工单清单的循环:下标版与取项版 const orders = [ { product: "凸轮轴", priority: "urgent", qty: 40 }, { product: "导套", priority: "normal", qty: 120 }, { product: "芯轴", priority: "urgent", qty: 8 }, ]; for (let i = 0; i < orders.length; i++) { console.log(i, orders[i].product); // 下标版:需要序号时用 } for (const order of orders) { if (order.priority === "urgent") { console.log("加急:", order.product, "数量", order.qty); // 取项版:只要内容不要序号,首选——不存在越界可能 } } let urgentQty = 0; for (const o of orders) { if (o.priority === "urgent") urgentQty += o.qty; } console.log("加急总数量:", urgentQty); // 统计累加:循环的经典用途

把语法串成一段完整逻辑

单独的语法点是珠子,真实代码是串起来的项链。需求:操作工在表单输入数量,脚本判断数量是否在设备产能区间内,并按加急与否给出排产提示。

// 产能校验小脚本:声明、类型、分支、循环全用上 const CAPACITY = { milling: 500, heat: 300 }; // 工序产能表 function checkCapacity(qtyInput, process, priority) { const qty = Number(qtyInput); // 表单输入先转数字 if (!Number.isFinite(qty) || qty <= 0) { return { ok: false, msg: "数量必须是正整数" }; // 参数体检先行 } const cap = CAPACITY[process] ?? 0; if (cap === 0) return { ok: false, msg: "未知工序" }; if (qty > cap) { return { ok: false, msg: `超出产能上限 ${cap},请拆单` }; // 模板字面量:反引号里用插值拼消息,4.7 节正式讲 } if (priority === "urgent" && qty > cap * 0.8) { return { ok: true, warn: "加急且占产能大半,建议错峰" }; } return { ok: true, warn: "" }; // 正常通过 } // 逐个用例走一遍(开发期的小型验收) console.log(checkCapacity("80", "heat", "normal")); // { ok: true, warn: "" }:热处理八十件常规单,正常 console.log(checkCapacity("400", "heat", "urgent")); // { ok: false, msg: "超出产能上限 300,请拆单" }:超产拦下 console.log("abc", "milling", "normal"); // 注意:直接打印字符串只是演示错误输入的形态,正式调用要传给函数
走查要点(对着输出逐条核对): - 返回值统一是对象:调用方只判 ok 字段,不用记多种返回形态 - 错误消息直接可读:给操作工看的话,不是给程序员看的堆栈 - 边界用例全覆盖:非法输入、未知工序、超产、加急大单、正常单

这段脚本的返回值设计值得多说一句:无论成功失败都返回同构的对象,调用方(未来的表单校验)不需要区分"返回的是字符串还是数字还是空",一个字段定生死——这种"契约先行"的写法会在整章反复出现。

⚠️ 常见坑:把老关键字与新关键字混用在同一文件。两者作用域规则不同,混用后"这变量到底在哪可见"变成玄学题。新文件从第一行就用新关键字,老代码读到 var 时能认出它即可。

💡 关键直觉:写任何一段逻辑前先想清楚"输入是什么类型、输出是什么形态",把这两个问题钉死,类型转换与分支判断都会自己站到位——多数语法错误其实是输入输出没想清楚的症状。

本节要点回顾

  • 声明三选一:现代代码只用块级可变与不可变两种声明,老关键字仅供认读;
  • 值与引用:基本类型拷贝内容、对象拷贝地址,数据"莫名被改"先查多标签共箱;
  • 严格比较:一律用严格相等,类型转换显式书写,空值与未定义语义有别;
  • 查表代替分支:枚举取值判断优先查表加空值合并,分支数骤减;
  • 取项循环:不要序号就用取每一项的写法,越界错误从根上消失;
  • 契约先行:函数返回同构对象,调用方一个字段判生死。

储物格有了,下一节学装集装箱:函数与作用域,把零散语句打成可复用的单元。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U