CoffeeScript 2.3.0 发布详解:ES2018 异步迭代器、对象 Rest/Spread、幂运算符与正则 s 标志
编程语言编译器【免费下载链接】coffeescriptUnfancy JavaScript项目地址https://gitcode.com/gh_mirrors/co/coffeescript点击查看免费下载本篇技术指南基于 CoffeeScript 仓库的 2.3.0 版本发布记录documentation/sections/changelog/2.3.0.md展开系统梳理该版本引入的 ES2018 语法支持异步迭代器yield await、对象 rest/spread 原生输出移除Object.assignpolyfill、幂运算符**/**以及正则表达式sdotAll标志。文中将结合仓库源码与测试用例说明每项特性的编译行为变化、使用前提与转译注意事项帮助读者理解 2.3.0 相较 2.2.4 的语义升级并安全地把这些新特性应用到自己的 CoffeeScript 项目中。版本概况与升级入口CoffeeScript 2.3.0 发布于 2018 年 4 月 29 日前一版本为 2.2.4见 changelog 首行的releaseHeader(2018-04-29, 2.3.0, 2.2.4)。该版本的核心使命是把 ES2018 中此前无法在 CoffeeScript 中直接表达的新语法全部纳入编译支持同时让编译输出更加原生化——不再依赖旧式 polyfill 或辅助函数而是直接产出符合 ES2018 规范的 JavaScript。升级前需要明确一个前提由于 2.3.0 的输出默认使用最新、最现代的 JavaScript 语法如果你的目标运行环境浏览器或 Node 版本不支持这些语法就必须在编译后叠加一层转译transpile。这一点在 changelog 中已明确强调详见下文转译小节与仓库的 转译指南。ES2018 支持全景四类新特性2.3.0 的语法支持更新可以归纳为以下四类本文后续各小节逐一深入特性类别ES2018 语法CoffeeScript 写法示例编译输出变化异步迭代器for await...of、异步生成器do - until file.EOF then yield await file.readLine()原生输出支持yield await对象 rest/spread对象展开与剩余属性{a, b, rest...} obj不再转为Object.assign调用直接输出原生语法幂运算**、**a ** 3不再转为Math.pow(a, 3)直接输出a ** 3正则标志sdotAll/a.b/s词法层接受s标志并原样输出异步迭代器与yield await异步迭代器Async Iterator是 ES2018 新增的迭代协议扩展允许以异步方式逐项消费数据流如按行读取文件、分页拉取接口数据。2.3.0 起CoffeeScript 可以在生成器函数中直接书写yield await让yield的值是一个被await解析后的 Promise 结果do - until file.EOF yield await file.readLine()这段代码对应 JavaScript 中的异步生成器每次next()调用都会返回一个 Promise消费者拿到后先await再取value从而按需逐行消费文件内容。for await循环与异步生成器除yield await外仓库测试 test/async_iterators.coffee 展示了两种配套用法for await ... from推导循环直接遍历异步可迭代对象createAsyncIterable (syncIterable) - for elem in syncIterable yield await winLater elem, 50 foo (x for await x from createAsyncIterable [1,2,3]) # foo [1, 2, 3]异步生成器函数的完整消费链路测试中先构造生成器再通过await ...next()取得结果foo (val) - yield await winLater val 1, 50 a await foo(41).next() # a.value 42该测试文件还验证了异步生成器在 Promise 被拒绝rejected时会把错误抛出到await侧failLater用例保证错误语义与原生异步迭代器一致。底层支撑isAsync与async function从源码结构看CoffeeScript 2 的 AST 节点已经内置了异步语义支持。在 src/nodes.coffee 中Code节点通过isAsync标记判定自身是否为异步函数src/nodes.coffee 在编译函数声明时根据该标记追加async关键字从而让yield await能落到正确的异步生成器上下文中。可以推断yield await之所以可行是因为编译器把含await的生成器函数编译为带async标记的生成器使yield与await在 ES2018 语义下协同工作。使用提示yield await依赖目标运行时对异步迭代器协议与异步生成器的原生支持在较旧的 Node如 10 以下或旧浏览器中运行前务必通过转译工具降级见下文转译小节。对象 Rest/Spread从 polyfill 到原生语法对象 rest/spread对象剩余属性与展开此前在 CoffeeScript 中已可用但一直是靠编译期展开为Object.assign调用来模拟。随着该语法在 ES2018 中被标准化2.3.0 移除了这层 polyfill 逻辑代码写什么就基本输出什么{a, b, rest...} obj在 2.3.0 之前会被编译为类似rest Object.assign({}, obj)之后再做属性剔除的辅助代码在 2.3.0 中则直接输出接近原文的原生对象剩余属性语法展开语法同理merged {source..., extra: 1}语义差异提醒polyfill 与原生实现并不完全等价changelog 特别提醒Object.assignpolyfill 与原生对象 rest/spread 实现之间存在细微差异。两者虽然都用于复制对象属性但在底层取值/赋值的时机与方式上并不一致例如对属性描述符、getter/setter 的处理不同。这意味着依赖Object.assign特有语义如复制时触发 setter、复制符号属性等的既有代码升级到 2.3.0 后应做回归验证以浅拷贝为目标的展开操作在绝大多数场景下行为一致可直接升级。测试佐证覆盖顺序与复杂嵌套仓库 test/object_rest_spread.coffee 对该特性有非常详尽的验证可作为行为规范参考覆盖顺序obj2 {obj..., a: 8, c: 9, obj...}的结果中obj2.c等于 3后面的展开覆盖前面的同名键说明输出保持书写顺序的原生 spread 语义test/object_rest_spread.coffee深层嵌套展开obj4 {a: 10, obj.c...}支持对任意深层子对象做展开test/object_rest_spread.coffee复杂解构剩余属性{{a...}...} b、{d.e...} f: 1等展开中的解构均可编译并正确取值test/object_rest_spread.coffee函数参数中的 rest(({a, b, r...}) - ...) obj允许在函数形参中使用对象剩余属性且测试特意验证了...不会触发隐式调用test/object_rest_spread.coffeesoak 与原型简写{withSoak?.b...}、{withPrototype::b...}等组合场景同样受支持test/object_rest_spread.coffee。幂运算符**与**ES2018 为 JavaScript 引入了幂运算符**和幂赋值运算符**。在 2.3.0 之前CoffeeScript 会把a ** 3编译为Math.pow(a, 3)2.3.0 起则直接原样输出a ** 3代码更贴近源码、可读性更好也免去了对Math.pow的运行时调用开销。a ** 3 # a ** 3此前为 Math.pow(a, 3) a ** 2 # a ** 2幂赋值编译器内部处理从源码可以确认词法层与语法层对**/**的完整支持src/lexer.coffee 的复合赋值操作符 token 列表明确包含**与//、%%等特殊数学赋值并列src/nodes.coffee 在赋值节点编译时对context is **做专门分支src/nodes.coffee 的compileSpecialMath方法会把这类特殊数学赋值转换为扩展形式如a ** b转换为a a ** b后再编译与//、%%共用同一套降级路径。使用提示**的优先级与结合性遵循 ES2018 规范右结合、优先级高于乘除。若你的代码库此前用Math.pow的习惯写法表达幂运算升级后编译产物会直接改为**运算符需要在支持 ES2018 语法的运行时中运行或转译。正则表达式sdotAll标志ES2018 新增了正则表达式的s标志dotAll使.可以匹配包括换行符在内的任意字符。2.3.0 在词法层即接受该标志并把它随正则原样输出pattern /a.b/s # . 现在也能匹配换行符词法层的标志校验正则标志的合法性在 src/lexer.coffee 中由两条规则控制REGEX_FLAGS /^\w*/负责从正则尾部捕获标志字符串VALID_FLAGS /^(?!.*(.).*\1)[gimsuy]*$/校验标志集合只能是g、i、m、s、u、y六者之一且不允许重复。可见s已正式列入合法标志白名单若书写了s之外或重复的标志src/lexer.coffee 会抛出invalid regular expression flags错误从词法阶段就阻止非法输入进入语法分析。配套的转义处理正则解析还配套了 src/helpers.coffee 的replaceUnicodeCodePointEscapes工具当正则没有u标志时把\u{...}形式的 Unicode 码点转义改写为传统的\uxxxx[\uxxxx]序列确保不同标志组合下都能正确编译。使用提示s标志需要运行时支持 ES2018 正则特性在旧浏览器中即使语法解析通过运行时也可能抛异常建议结合转译或目标环境兼容性测试验证。转译让新语法跑在旧运行时changelog 中明确要求对于上述所有新特性除非你确认目标运行时全部支持否则请先转译再上线。CoffeeScript 内置了对 Babel 转译器的支持仓库 转译指南 给出了完整流程。命令行快速上手npm install --save-dev babel/core babel/preset-env echo { presets: [babel/env] } .babelrc coffee --compile --transpile --inline-map some-file.coffee其中--transpile开启 Babel 转译管道把 CoffeeScript 编译产物再交给 Babel 处理--inline-map同时产出内联 source map便于调试转译后的代码.babelrc中的babel/envpreset即babel/preset-env负责根据目标环境自动选择需要转换的语法插件。Node API 方式使用CoffeeScript.compile时options对象中的transpile键直接透传为 Babel 配置CoffeeScript.compile(code, {transpile: {presets: [babel/env]}})Polyfill 的补充说明需要注意转译语法降级并不会自动补齐运行时缺失的内置 APIpolyfill。例如 CoffeeScript 输出中可能出现的Array.indexOfin运算符、解构、rest/spread 相关场景与Function.bind类中绑定方法等在需要支持 IE8 及以下等老环境时仍需自行引入 polyfill详见 转译指南 的 Polyfills 小节。总结CoffeeScript 2.3.0 是面向 ES2018 的一次原生语法化升级异步迭代器yield await、对象 rest/spread、幂运算符**/**与正则s标志均从模拟实现走向原生输出编译产物更干净、更贴近现代 JavaScript。同时版本对运行环境提出了更高要求仓库提供了成熟的--transpile/Node API 转译路径作为兼容保障。升级到该版本后建议重点回归三类代码依赖Object.assign复制语义的对象展开、依赖Math.pow的幂运算表达式以及涉及正则标志组合的匹配逻辑。相关深入阅读转译指南、异步迭代器测试 test/async_iterators.coffee、对象 rest/spread 测试 test/object_rest_spread.coffee、正则标志校验实现 src/lexer.coffee。赞分享编程语言编译器【免费下载链接】coffeescriptUnfancy JavaScript项目地址https://gitcode.com/gh_mirrors/co/coffeescript点击查看免费下载相关推荐ESLint rest-spread-spacing 规则详解统一 rest/spread 运算符与表达式之间的空白ESLint rest spread spacing 规则详解统一 rest/spread 运算符与表达式之间的空白 本文围绕 ESLint 内置的 rest开发工具Lint静态分析代码质量ESLint prefer-spread 规则详解用展开运算符替代 Function.prototype.apply()ESLint prefer spread 规则详解用展开运算符替代 Function.prototype.apply 导读 prefer spread 是 E开发工具Lint静态分析代码质量Cloudflare Workers 兼容性标志 fetch_iterable_type_support 详解让同步/异步可迭代对象正确成为 fetch 请求体Cloudflare Workers 兼容性标志 fetch_iterable_type_support 详解让同步/异步可迭代对象正确成为 fetch 请求文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考