ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ESLint prefer-numeric-literals 规则详解:用二进制、八进制与十六进制字面量取代 parseInt()

ESLint prefer-numeric-literals 规则详解:用二进制、八进制与十六进制字面量取代 parseInt() ESLint prefer-numeric-literals 规则详解用二进制、八进制与十六进制字面量取代 parseInt()【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslintprefer-numeric-literals是 ESLint 内置的一条 suggestion 类型规则它鼓励开发者在 ES6 及以上环境中用0b、0o、0x前缀的数字字面量替代parseInt()/Number.parseInt()对二进制、八进制、十六进制字符串的解析。本文基于 prefer-numeric-literals 官方文档 展开并结合该规则在仓库中的源码实现与单元测试完整讲解规则的触发条件、正确与错误示例、自动修复机制、边界行为以及适用前提帮助你准确地在项目中启用并驾驭这条规则。规则背景为什么要用数字字面量替代 parseInt()在 ES6ECMAScript 2015之前JavaScript 没有二进制的字面量语法八进制字面量的写法也不够统一因此要将形如111110111、767、1F7这样的二进制、八进制或十六进制字符串转换为整数只能借助parseInt()或Number.parseInt()这类函数parseInt(111110111, 2) 503; parseInt(767, 8) 503; parseInt(1F7, 16) 503;ES6 之后JavaScript 原生支持了带前缀的数字字面量语义上与上述解析结果完全等价0b111110111 503; 0o767 503; 0x1F7 503;从源码的元数据可以确认该规则的定位是suggestion建议类默认不启用recommended: false属于frozen: true的冻结规则即其行为与选项一旦定型便不再变更参见 lib/rules/prefer-numeric-literals.js 与 docs/src/_data/rules.json。它自 ESLint 3.5.0 版本引入见 docs/src/_data/rule_versions.json并可通过--fix自动修复。Rule Details规则的精确触发条件规则的核心判定逻辑位于 lib/rules/prefer-numeric-literals.js 的create(context)中。它监听CallExpression[arguments.length2]节点即恰好传入两个实参的函数调用并同时满足以下全部条件时才报告问题被调用的函数必须是parseInt或Number.parseInt。源码中的isParseInt()辅助函数lib/rules/prefer-numeric-literals.js负责识别 callee对裸标识符parseInt要求它是全局引用sourceCode.isGlobalReference即作用域内没有被局部变量遮蔽对成员访问Number.parseInt要求Number本身也是全局引用且支持通过skipChainExpression处理可选链写法如Number?.parseInt。第一个参数必须是字符串字面量源码要求astUtils.isStringLiteral(strNode)且astUtils.getStaticStringValue(strNode)返回非null。这意味着普通字符串字面量111110111和无表达式的模板字符串111110111均会被命中而包含插值${foo}的模板字符串、正则字面量或变量引用则不会见 lib/rules/utils/ast-utils.js。第二个参数必须是数值型的字面量且值恰好为 2、8 或 16。源码通过radixMap维护进制与字面量前缀的映射const radixMap new Map([ [2, { system: binary, literalPrefix: 0b }], [8, { system: octal, literalPrefix: 0o }], [16, { system: hexadecimal, literalPrefix: 0x }], ]);注意这里要求的是Literal节点且值为number类型——字符串形式的2、BigInt 形式的2n都不满足条件不会触发报告这一点在 tests/lib/rules/prefer-numeric-literals.js 的 valid 用例中明确验证。一旦命中规则会报告消息Use {{system}} literals instead of {{functionName}}().例如 Use binary literals instead of parseInt().消息模板见 lib/rules/prefer-numeric-literals.js。错误代码示例incorrect以下代码均会触发该规则示例取自 docs/src/rules/prefer-numeric-literals.md/*eslint prefer-numeric-literals: error*/ parseInt(111110111, 2) 503; parseInt(111110111, 2) 503; parseInt(767, 8) 503; parseInt(1F7, 16) 503; Number.parseInt(111110111, 2) 503; Number.parseInt(767, 8) 503; Number.parseInt(1F7, 16) 503;正确代码示例correct以下代码不会触发该规则示例取自 docs/src/rules/prefer-numeric-literals.md它们分别覆盖了“参数个数不符合”“进制不符合”“字符串不是字面量”等被规则豁免的情况/*eslint prefer-numeric-literals: error*/ parseInt(1); parseInt(1, 3); Number.parseInt(1); Number.parseInt(1, 3); 0b111110111 503; 0o767 503; 0x1F7 503; aparseInt; parseInt(foo); parseInt(foo, 2); Number.parseInt(foo); Number.parseInt(foo, 2);逐条解读这些豁免场景parseInt(1)/parseInt(1, 3)第一个参数不是字符串或进制不是 2/8/16aparseInt通过计算成员访问调用callee 不是parseInt标识符本身parseInt(foo)/parseInt(foo, 2)第一个参数是变量而非字符串字面量字符串内容无法静态确定直接书写的0b/0o/0x字面量本身就是规则提倡的写法自然不会报告。被遮蔽的全局函数不会被报告从测试用例tests/lib/rules/prefer-numeric-literals.js可以看到如果parseInt或Number在局部作用域被声明遮蔽则不再视为全局引用规则会放行function foo(parseInt) { parseInt(111110111, 2); } function foo(Number) { Number.parseInt(111110111, 2); }这一点得益于isParseInt()中对sourceCode.isGlobalReference的调用其实现位于 lib/languages/js/source-code/source-code.js会结合作用域分析判断标识符是否真正引用全局变量。自动修复Autofix机制与安全边界该规则声明为fixable: code见 lib/rules/prefer-numeric-literals.js即可以通过eslint --fix或编辑器的“快速修复”将parseInt(111110111, 2)直接改写为0b111110111。修复逻辑位于 lib/rules/prefer-numeric-literals.js并且内置了多层安全防护以下情况不会生成修复但仍会报告生成的数字字面量无效例如parseInt(1234, 2)生成的0b1234不是合法的二进制字面量parseInt(7999, 8)生成的0o7999不是合法的八进制字面量parseInt(1234.5, 8)不是整数修复会被跳过。源码通过replacement ! parseInt(str, radix)这一校验来保证替换前后语义完全一致lib/rules/prefer-numeric-literals.js。字符串含数字分隔符numeric separatorsparseInt(1_1, 2)的解析结果是1遇到_停止而0b1_1的值是3二者不等价且一元按规范不支持数字分隔符会得到NaN因此校验必然失败、不进行修复。测试用例如parseInt(1_0, 2)、Number.parseInt(5_000, 8)均验证了此行为tests/lib/rules/prefer-numeric-literals.js。空字符串parseInt(, 8)生成的字面量为空无法修复。调用表达式内部或函数名两侧存在注释如果修复会移除或破坏注释如Number/**/.parseInt(11, 2)、parseInt/**/(11, 2)规则会保守地放弃修复。测试用例覆盖了多达十余种注释位置组合tests/lib/rules/prefer-numeric-literals.js。包含表情符号等非常规字符parseInt(1️⃣3️⃣3️⃣7️⃣, 16)无法转换为等价的数字字面量不会修复tests/lib/rules/prefer-numeric-literals.js。此外修复器还会处理相邻 token 的空格问题利用astUtils.canTokensBeAdjacent判断替换后的字面量与前后 token 是否可能粘连例如5parseInt(A, 16)会被修复为50xA而parseInt(11, 2)in foo会被修复为0b11 in foo以避免0b11in粘连必要时自动补充空格lib/rules/prefer-numeric-literals.js。一个完整的修复示例与测试中的 invalid 用例一一对应修复前修复后parseInt(111110111, 2)0b111110111parseInt(767, 8)0o767parseInt(1F7, 16)0x1F7Number.parseInt(111110111, 2)0b111110111parseInt(111110111, 2)0b111110111模板字符串同样可修复parseInt?.(1F7, 16)0x1F7可选链调用同样可修复可选链相关的修复能力在测试的 Optional chaining 分组中有系统验证tests/lib/rules/prefer-numeric-literals.js。Options本规则没有可配置项与许多带复杂选项的规则不同prefer-numeric-literals没有任何选项。这一点在 docs/src/rules/prefer-numeric-literals.md 中明确说明同时源码中的schema: []lib/rules/prefer-numeric-literals.js也印证了它不接受任何配置参数。因此启用时只需指定错误级别即可{ rules: { prefer-numeric-literals: error } }或使用更灵活的错误级别warn{ rules: { prefer-numeric-literals: warn } }由于没有选项它也不会产生 suggestion 类带--fix-type suggestion的提示元数据中hasSuggestions: false见 docs/src/_data/rules.json。When Not To Use It何时应禁用此规则官方文档给出了两类明确的不适用场景docs/src/rules/prefer-numeric-literals.md你希望允许继续使用parseInt()/Number.parseInt()解析二进制、八进制、十六进制字符串。例如字符串内容来自外部输入或配置、运行时才能确定此时用字面量并不现实规则的价值有限你的项目不支持 ES6。二进制字面量0b和八进制字面量0o是 ES6 新增语法ES5 及更早版本无法解析这些写法。如果目标环境是 ES5 或更早的浏览器/运行时就必须禁用该规则否则替换后的代码根本无法运行。在支持 ES6 及以上语法的现代项目中该规则可以在不改变数值语义的前提下让代码更简洁、更易读同时减少一次函数调用。它不包含在eslint:recommended预设中recommended: false属于按需启用的建议类规则。扩展视角从源码看规则的设计取舍通读 lib/rules/prefer-numeric-literals.js 全文可以总结出这条规则在设计上的几个值得注意的点严格限定字面量输入规则只对“第一个参数是字符串字面量含无插值模板字符串”的情况生效因为只有字符串内容可静态确定时替换才是安全且可验证的。变量、函数调用结果、带插值的模板字符串均被排除。修复必须语义等价每次修复前都会用一元计算替换后字面量的实际数值并与parseInt(str, radix)的结果比较任何不等价的情况都会放弃修复——这保证了--fix永远不会改变程序的运行结果。对现代语法友好可选链parseInt?.、Number?.parseInt、数字分隔符等新特性都被显式处理测试覆盖完备体现了规则对 ES 新语法的持续跟进。总结prefer-numeric-literals是一条小而精的 ESLint 建议类规则它把“用函数解析非十进制字符串”这一 ES6 之前的惯用法引导为使用原生数字字面量的现代写法。规则本身零配置、可自动修复且在修复安全上做了大量防御性设计。启用前请确认项目运行在支持 ES6 的环境之后即可放心开启{ rules: { prefer-numeric-literals: error } }如需进一步研究可继续查看规则源码、完整单元测试以及该规则在规则目录中的元数据声明。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表