ESLint dot-notation 规则完全指南:强制使用点表示法访问对象属性
【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint
dot-notation是 ESLint 内置的一条 suggestion 类型规则,核心目标是维护代码风格一致性、提升可读性,鼓励开发者在能够使用点表示法(foo.bar)的地方不要使用方括号表示法(foo["bar"])。本指南将以 关联文档 为主体,结合当前仓库的 规则源码 与 完整测试用例,系统讲解该规则的触发条件、两个可配置选项(allowKeywords、allowPattern)、自动修复行为以及众多边界情况,帮助你在实际项目中正确配置并使用这一规则。
为什么优先使用点表示法
在 JavaScript 中,访问对象属性有两种等价写法:点表示法foo.bar和方括号表示法foo["bar"]。虽然两者语义相同,但点表示法通常更受青睐,原因有三:
- 更易阅读:
foo.bar比foo["bar"]更简洁直观,视觉噪音更少; - 更少冗长:省略了引号和方括号,代码更紧凑;
- 对压缩工具更友好:配合激进的 JavaScript 压缩器(minimizer)时,点表示法更利于属性名压缩与混淆。
原文档中给出的反例foo["bar"];正是规则要拦截的典型写法。
Rule Details:规则何时发出警告
该规则的目标是“在尽可能的情况下”鼓励使用点表示法。当代码中出现不必要的方括号表示法时,规则会发出警告。所谓“不必要”,是指属性名本身是一个合法的标识符(符合 JavaScript 标识符命名规范),完全可以直接跟在点号后面。
判断的精确条件(详见 lib/rules/dot-notation.js 中checkComputedProperty函数)为:属性名同时满足——
- 匹配合法标识符正则
/^[a-zA-Z_$][\w$]*$/u; - (在
allowKeywords: false时)不是 ES3 保留字; - (在配置了
allowPattern时)不匹配允许使用方括号记法的模式。
错误示例(应改为点表示法)
/*eslint dot-notation: "error"*/ const x = foo["bar"]; // 报错:"bar" 是合法标识符,应写作 foo.bar正确示例(不应报错)
/*eslint dot-notation: "error"*/ const x = foo.bar; // 已经是点表示法 const y = foo[bar]; // 属性名是变量,必须用方括号,规则不会触发第二行foo[bar]中bar是一个变量而非字符串字面量,属性名在运行时才能确定,此时方括号表示法是唯一正确的写法,因此规则放行。这一点也直接体现在源码中:MemberExpression的检查分支要求node.property.type === "Literal"(字符串/布尔/null字面量)或静态模板字面量(无插值的`bar`)才进入checkComputedProperty,而变量属性(Identifier)不在检查范围内(lib/rules/dot-notation.js)。
Options:两个可配置选项
规则接受单个对象作为选项,完整 schema 定义在 lib/rules/dot-notation.js:
| 选项 | 类型 | 默认值 | 作用 |
|---|---|---|---|
allowKeywords | boolean | true | 设为false时遵循 ECMAScript 3 兼容风格,对保留字属性禁止使用点表示法 |
allowPattern | string | ""(空字符串,即不测试任何模式) | 正则表达式字符串,匹配该模式的属性名允许继续使用方括号表示法 |
两者的默认值同样固化在defaultOptions中(lib/rules/dot-notation.js)。
allowKeywords
默认情况下(allowKeywords: true),像foo.class、foo.true、foo.null这类使用保留字作属性名的点表示法是允许的,因为现代 JavaScript 引擎(ES5 及之后)已支持在点号后使用保留字。但如果你需要兼容 ES3 风格的代码,可以显式关闭:
/*eslint dot-notation: ["error", { "allowKeywords": false }]*/ const foo = { "class": "CS 101" } const x = foo["class"]; // 属性名是保留字,必须用方括号表示法上面代码是{ "allowKeywords": false }下的正确写法。此时规则会反过来工作:对foo.class这类写法报错,提示改用方括号。消息为.class is a syntax error.(源码中useBrackets消息,lib/rules/dot-notation.js),并自动修复为foo["class"]。测试用例a.true;→a["true"];即验证了该行为(tests/lib/rules/dot-notation.js)。
私有字段特例:对于类私有标识符(private identifier),点表示法是强制语法,不能使用方括号,因此规则不会干预:
/*eslint dot-notation: ["error", { "allowKeywords": false }]*/ class C { #in; foo() { this.#in; // 私有标识符必须使用点表示法 } }对应测试见 tests/lib/rules/dot-notation.js。另外,this['#a']这类把私有字段名写成字符串的形式同样不会被转换(tests/lib/rules/dot-notation.js)。
allowPattern:与 camelcase 规则协同
实际开发中,向外部 API 发送数据时,常常需要携带包含下划线的属性名(snake_case 风格)。如果项目中同时启用了camelcase规则,这些下划线属性会被禁止使用驼峰以外的命名。此时可以给dot-notation配置allowPattern,让匹配该正则的属性名继续使用方括号表示法,形成互补。
以下配置允许属性名匹配^[a-z]+(_[a-z]+)+$(即 snake case 模式)时使用方括号:
/*eslint dot-notation: ["error", { "allowPattern": "^[a-z]+(_[a-z]+)+$" }]*/错误示例(不匹配模式,应使用点表示法):
const data = {}; data["fooBar"] = 42; // "fooBar" 是驼峰命名,应写作 data.fooBar正确示例(匹配模式,方括号被放行):
const data = {}; data["foo_bar"] = 42; // "foo_bar" 匹配 snake case 模式,允许方括号从源码看,allowPattern被编译为带u标志的正则(lib/rules/dot-notation.js),仅当模式非空时才生效;当属性名匹配该模式时,规则跳过报错。测试还验证了模式外的写法会被正常修复:a['_dangle'](以下划线开头)和a['SHOUT_CASE'](全大写)都会在配置该模式后仍被改为点表示法(tests/lib/rules/dot-notation.js)。
源码级实现剖析:哪些写法会被检查
规则仅监听MemberExpression节点(lib/rules/dot-notation.js),核心检查逻辑可归纳为两类:
1. 方括号 → 点(主方向,默认行为)
当成员表达式满足computed为真,且属性是以下字面量之一时,进入转换检查:
- 字符串字面量,如
foo["bar"]; - 布尔字面量
true/false,如foo[true]; null字面量,如foo[null](源码中用literalTypesToCheck集合专门区分null,因为typeof null === "object",见 lib/rules/dot-notation.js);- 静态模板字面量(无插值),如
foo[`time`],会被转换为foo.time(判定函数isStaticTemplateLiteral要求expressions.length === 0,见 lib/rules/utils/ast-utils.js)。
注意:数字下标a[0]、变量a[b]、含插值的模板字符串a[`time${range}`]都不会触发检查——它们本就无法用点表示法表达,测试中均列为valid(tests/lib/rules/dot-notation.js)。
2. 点 → 方括号(仅allowKeywords: false时)
当allowKeywords: false且成员表达式为非 computed、属性为标识符且命中了 ES3 保留字(列表见 lib/rules/utils/keywords.js 中的keywords数组,包含class、while、true、null等 60 余个词)时,规则反向报错并建议改写为方括号。此时消息为useBrackets。
自动修复(fix)的细节
规则声明了fixable: "code"(lib/rules/dot-notation.js),可在--fix模式下自动改写代码,但修复器内部做了多处谨慎处理:
- 括号内有注释时不修复:如
foo[ /* comment */ 'bar' ]或foo. /* comment */ while,仅报告错误,避免破坏注释(对应测试输出为null,tests/lib/rules/dot-notation.js); - 数字字面量补空格:
1['toString']会被修复为1 .toString(而非1.toString,后者会与数字字面量粘连产生语法歧义)。源码用astUtils.isDecimalInteger(node.object)判断对象是否为纯十进制整数,决定是否插入空格(lib/rules/dot-notation.js);测试覆盖了5['prop']、-5['prop']、08['prop']、01['prop']、5_000['prop'](数值分隔符)等多种数字形态(tests/lib/rules/dot-notation.js); - 相邻 token 补空格:修复后若属性与下一个 token 直接相连且不能相邻(如
foo['bar']instanceof baz),会自动插入空格变成foo.bar instanceof baz(lib/rules/dot-notation.js); - 可选链支持:
obj?.['prop']可修复为obj?.prop,obj?.true在allowKeywords: false下可修复为obj?.["true"](tests/lib/rules/dot-notation.js); - 避免破坏解构语法:
let.if()在allowKeywords: false下不执行修复,因为let["if"]()中的let[会被解析为解构变量声明,属于语法错误(源码注释明确说明这一点,lib/rules/dot-notation.js)。
边界行为速查(来自测试套件)
以下行为全部有 tests/lib/rules/dot-notation.js 中的对应用例佐证,可作为理解规则语义的速查表:
| 代码 | 默认行为 | 备注 |
|---|---|---|
a['12']、a[0] | 不报错 | 属性名不是合法标识符,无法用点表示法 |
a[undefined]、a[void 0]、a[b()] | 不报错 | 非字面量属性,只能方括号 |
a[/(?<zero>0)/] | 不报错 | 正则字面量属性 |
a['while'] | 默认报错并修复为a.while | allowKeywords: false时放行 |
a['null']、a[null] | 报错并修复为a.null | null字面量单独处理 |
foo[('bar')]、(foo)['bar'] | 报错并修复 | 括号包裹不影响修复 |
foo\n .while; | allowKeywords: false时报错 | 跨行修复为foo["while"] |
Promise 链"catch" | 报错并修复为.catch(fn) | 保留跨行链式结构 |
值得一提的是 Promise 链示例:getResource().then(...)"catch"会被逐一修复为.catch(...)(tests/lib/rules/dot-notation.js),这在实际代码中非常常见,也是该规则在默认配置下高频命中的场景之一。
如何在项目中启用与配置
单独启用
// eslint.config.js(flat config) export default [ { rules: { "dot-notation": ["error", { "allowKeywords": false, "allowPattern": "^[a-z]+(_[a-z]+)+$" }], }, }, ];配合 camelcase 的推荐组合
当接口数据字段采用 snake_case、而代码风格要求 camelCase 时,可以这样组合使用:
export default [ { rules: { camelcase: ["error", { properties: "never" }], "dot-notation": ["error", { "allowPattern": "^[a-z]+(_[a-z]+)+$" }], }, }, ];这样,data["foo_bar"]被allowPattern放行,而data["fooBar"]则会被规则要求改写为data.fooBar,两条规则分工明确、互不冲突。
注意:dot-notation并未包含在 ESLint 的recommended配置中(meta.docs.recommended为false,见 lib/rules/dot-notation.js),需要团队自行决定是否开启及如何配置。
规则元信息一览
最后汇总该规则的元数据(lib/rules/dot-notation.js),便于在文档与工具链中快速检索:
- 规则类型(type):
suggestion——提供风格层面的改进建议,不影响程序正确性; - 是否推荐(recommended):否,需显式开启;
- 是否可自动修复(fixable):
code,--fix可安全改写; - 消息模板:
useDot([{{key}}] is better written in dot notation.)与useBrackets(.{{key}} is a syntax error.); - 默认选项:
{ allowKeywords: true, allowPattern: "" }; - 注册入口:lib/rules/index.js 中以懒加载方式导出。
总结
dot-notation通过“能点就不带括号”的简单策略,显著提升了 JavaScript 代码的可读性与压缩友好度。理解它的两个选项便能应对绝大多数场景:默认配置适合现代 JavaScript 代码库;allowKeywords: false服务于 ES3 兼容风格;allowPattern则是在 snake_case 数据与 camelCase 代码风格之间取得平衡的利器。结合其完善的自动修复能力与对注释、数字字面量、可选链、私有字段等边界情况的细腻处理,这是一条开箱即用、值得纳入团队规范的风格类规则。
【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考