4.7 ES6+现代语法:标准接线工艺


4.7 ES6+ 现代语法:标准接线工艺

本节摘要:语言标准每隔一年迭代一批特性,箭头函数、模板字面量、解构、类与模块是现代前端的通用语。本节把这些特性按"旧写法对照新写法"的方式过一遍,讲清箭头函数与普通函数在指向上的差别、类语法糖的成分、模块化导出导入的分工,最后看一眼标准演进的节奏与兼容策略。

新工装上手:一条一条换装

前面各节已经零散用过现代语法,这里系统换装。每件新工装的价值都指向同一个方向:更少的样板、更明确的意图。读懂别人的现代代码不再隔一层方言,是本节最实际的收益——框架文档、开源项目、面试白板,说的全是这套话。

// 换装一:箭头函数——函数的三种缩写 const double = (n) => n * 2; // 单参数省圆括号、单表达式省花括号与返回关键字 const add = (a, b) => a + b; const label = (status) => ({ pending: "待开工", running: "加工中", }[status] ?? "未知"); // 返回对象字面量时套一层圆括号,避免与函数体花括号混淆 const old = function (n) { return n * 2; }; // 普通函数仍有一席之地:做构造器、需要自身指向的场景
// 换装二:箭头函数的指向差别——它没有自己的"自己" function Timer() { this.seconds = 0; } Timer.prototype.start = function () { setInterval(() => { this.seconds += 1; // 箭头函数继承外层的"自己":这里的 this 就是定时器实例 // 若换成普通函数,this 指向全局或未定义——历史头号坑就此填平 }, 1000); }; // 经验法则:方法内回调用箭头函数,顶层或构造用普通函数 // 换装三:模板字面量——字符串的拼装台 const no = "MO-1042"; const line = `工单 ${no}:${double(21)} 件,状态正常`; // 反引号内插值:变量与表达式直接嵌入,告别加号连缀 const html = ` <tr> <td>${no}</td> </tr>`; // 还支持原样换行:拼标记模板不再一行写到天边

解构、展开与默认值:搬运三件套

4.3 节用过解构与展开,这里补齐它们在函数签名与参数处理上的完整形态。三件套的共同思想是"按形状拆装":数据的形状写在哪,拆装规则就在哪,中间过程零代码。

// 函数签名的解构与默认值 function renderCard({ no, product, qty = 0, priority = "normal" }) { // 参数即形状:调用方传对象,函数体直接用字段,缺省就地补 const tag = priority === "urgent" ? "【加急】" : ""; console.log(`${tag}${no} ${product} × ${qty}`); } renderCard({ no: "MO-1046", product: "压板" }); // 缺的数量按零处理 // 变量交换与多重返回 let a = 1, b = 2; [a, b] = [b, a]; // 交换:不再需要临时变量 function findOrder(orders, no) { const idx = orders.findIndex((o) => o.no === no); return { found: idx >= 0, order: orders[idx], idx }; // 多重返回打包成对象 } const { found, order } = findOrder(orders, "MO-1043"); const { found: ok2, order: second } = findOrder(orders, "MO-1043"); // 解构时改名:避免与现有变量撞名
// 展开的四个高频用法 const today = [...yesterday, ...todayNew]; // 合并:两个工单数组成一份今日清单 const patched = { ...order, status: "running" }; // 覆盖:复制旧对象并改字段(4.3 节的不可变更新) function register(product, ...opts) { // 收集:剩余参数打包成数组——替代老式的参数对象 console.log(product, opts); } register("凸轮轴", 40, "陈师傅"); // "凸轮轴" [40, "陈师傅"] const merged = { ...defaults, ...userPrefs }; // 配置合并:默认值打底、用户偏好覆盖——配置系统的标准姿势

类语法:原型体系的工整写法

对象的行为共享历史上靠原型链实现,写法散漫难读。类语法把它收进一个工整的壳:构造器管出生初始化,方法管行为,继承管家族。壳还是那个原型壳(所以叫语法糖),但代码的组织结构立刻现代起来。看板的工单实体可以用类重写一遍。

// 工单实体:类的写法 class Order { constructor({ no, product, qty, priority = "normal", status = "pending" }) { // 出生初始化:参数解构加默认值,前两节的工装全用上 this.no = no; this.product = product; this.qty = qty; this.priority = priority; this.status = status; } get label() { // 取值器:像字段一样访问,实为方法计算 return `${this.no} ${this.product}`; } get urgent() { return this.priority === "urgent"; } advance() { if (this.status === "done") return this; this.status = this.status === "pending" ? "running" : "done"; return this; // 返回自身支持链式调用 } static from(raw) { // 静态方法:挂在类上而非实例上——工厂方法的惯例位置 return new Order(raw); } } const o = Order.from({ no: "MO-1046", product: "压板", qty: 30 }); o.advance().advance(); // 链式推进两步 console.log(o.label, o.status); // MO-1046 压板 done
// 继承:加急单是工单的特化 class UrgentOrder extends Order { constructor(raw) { super({ ...raw, priority: "urgent" }); // 先让父类出生 this.deadlineHours = raw.deadlineHours ?? 4; } advance() { super.advance(); // 复用父类推进 if (this.status === "running") console.log(`加急单 ${this.no} 巡检提醒`); return this; } } const u = new UrgentOrder({ no: "MO-1047", product: "阀体", qty: 10 }); console.log(u.urgent, u.deadlineHours); // true 4

模块化:文件即边界

脚本写大后拆文件是必然。模块化体系给每个文件一个边界:文件里声明的东西默认私有,导出什么、导入什么全部显式声明。依赖关系第一次变得可审计——谁用了谁,一张导入清单说清。前端的模块浏览器原生支持,脚本标签带上类型标记即可生效。

// 工具模块:导出两种形态 // —— 统计与常量可以分文件维护 —— const STATUS_LABEL = { pending: "待开工", running: "加工中", done: "已完成" }; function summarize(orders) { const count = (s) => orders.filter((o) => o.status === s).length; return { pending: count("pending"), running: count("running"), done: count("done"), }; } export { STATUS_LABEL, summarize }; // 命名导出:可多个,导入时按名取、花括号包裹 export default function renderOrders(orders) { /* 渲染实现 */ } // 默认导出:每文件至多一个,代表本文件的主打内容
// 主模块:导入并使用 import render from "./render-module.js"; // 默认导出的导入:名字自取,代表整个模块的主打 import { STATUS_LABEL, summarize } from "./stats-module.js"; // 命名导出的导入:名字必须对上 import * as stats from "./stats-module.js"; // 整体导入:模块全部内容打包成一个命名空间对象 console.log(stats.summarize(orders)); // 主模块在页面里的挂载方式:脚本标签声明模块类型 // 浏览器按模块语义加载:导入语句自动发起依赖请求

标准演进与兼容策略

语言标准如今每年夏天发一版,新特性源源不断。对待演进的健康姿势:核心特性(本节这些)是通行语必须精通;年度新特性按需学习,用到再查不丢人。兼容方面,主流浏览器的自动更新让新标准的落地越来越快,但车间里总有几台跑着老浏览器的旧平板——5.2 节会讲转译与补齐的工程手段,让新写法安全跑在老设备上。

⚠️ 常见坑:为炫技把一切函数写成箭头、把一切数据包成类。箭头函数没有自身指向,需要动态指向的场合(事件解绑、构造)会出诡异问题;只有行为与状态的数据用对象加函数就够,类的登场时机是"确实存在一族共享行为的实体"。

💡 关键直觉:读现代代码遇到陌生符号,先猜它是哪件旧工装的缩写——九成新语法是旧写法的减省。反着练也有效:把自己写的老式代码逐条换装,换完再对照官方写法找差距。

本节要点回顾

  • 箭头函数:三种缩写省样板;没有自身指向,回调首选、构造器勿用;
  • 模板字面量:插值与多行字符串,拼消息与拼标记的标准工具;
  • 搬运三件套:解构按形状拆、展开按形状装、默认值就地补,签名即形状;
  • 类语法糖:构造器、取值器、静态工厂、继承的工整壳,底下仍是原型;
  • 模块边界:文件私有、导出显式、依赖可审计,默认导出每文件至多一个;
  • 演进姿势:核心特性精通、年度特性按需,老设备的兼容交给工程手段。

工装齐了,下一节是行为班的质检台:存储、调试与排错,看板做通电总验收。


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