ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

eslint-plugin-unicorn 规则解析:no-array-method-this-argument 如何消灭多余的 `thisArg` 实参

eslint-plugin-unicorn 规则解析:no-array-method-this-argument 如何消灭多余的 `thisArg` 实参 eslint-plugin-unicorn 规则解析no-array-method-this-argument 如何消灭多余的thisArg实参【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn本指南以 eslint-plugin-unicorn 仓库中no-array-method-this-argument规则的 AVA 快照报告 为主体结合 规则实现、规则文档 与 单元测试 源码级剖析该规则的全部行为它检查哪些数组方法、何时自动修复、何时给出建议、如何处理 TypeScript 与边界语法以及快照测试如何成为规则行为的活文档。一、规则背景为什么禁止thisArg实参很多 JS 数组方法接受第二个实参thisArg用于在回调执行时把this绑定到指定对象const foo bar.find(function (element) { return this.isUnicorn(element); }, baz); // baz 会作为回调的 this规则文档 给出了禁止它的两条核心理由如果回调是箭头函数或已绑定的函数thisArg根本不会生效——箭头函数的this来自词法作用域bind()产生的函数无法再次被绑定。此时thisArg是一个纯粹的无效参数容易误导读者如果确实想在回调中使用自定义this直接引用变量闭包或使用callback.bind(thisArg)是更清晰、更显式的写法不依赖数组方法签名里的隐藏参数。因此该规则对在数组方法中传入this参数的行为直接报告错误rule type 为suggestion见 rules/no-array-method-this-argument.js。二、规则覆盖的方法范围该规则通过两个独立的CallExpression监听器实现见 rules/no-array-method-this-argument.js原型方法回调 thisArg共 2 个实参方法快照用例Array#every()invalid(1)Array#filter()invalid(2)Array#find()invalid(3)Array#findLast()invalid(4)Array#findIndex()invalid(5)Array#findLastIndex()invalid(6)Array#flatMap()invalid(7)Array#forEach()invalid(8)Array#map()invalid(9)Array#some()invalid(10)静态方法可迭代对象 回调 thisArg共 3 个实参Array.from()——快照invalid(14)Array.fromAsync()——快照invalid(15)。规则要求argumentsLength精确匹配2 或 3因此实参过多、过少、使用展开运算符...thisArgument的调用都不会被报告——这从 测试文件 的 valid 用例可以确认array.map(() {}, thisArgument, extraArgument)、Array.from(iterableOrArrayLike, () {}, ...thisArgument)均被视为合法。三、快照中的核心行为自动修复与建议的分野快照报告将全部 56 个 invalid 用例按回调形态分为两组这正是规则内部两条截然不同的处理路径3.1 箭头函数回调尽可能自动修复当第一个实参是ArrowFunctionExpression时快照第一组invalid(1)invalid(30)规则首先用hasSideEffect检查thisArg表达式是否包含副作用getter、函数调用、属性访问等thisArg无副作用直接给出fix可被eslint --fix自动应用。例如快照invalid(1)输入 array.every(() {}, thisArgument) 输出 array.every(() {}) 消息 Do not use the this argument in Array#every().thisArg有副作用如invalid(20)的array.map(() {}, thisArgumentHasSideEffect())删除它会改变程序语义因此规则不做自动修复只提供一个名为 Remove this argument. 的编辑器建议suggestion由开发者手动确认后应用。删除会波及注释如invalid(25)array.map(() {}, /* comment */ thisArgument)与invalid(26)array.map(callback, /* comment */ thisArgument)快照中只输出错误消息而没有 Output 与 Suggestion说明修复被安全地放弃了——规则源码 通过wouldRemoveComments在生成修复前做了拦截。值得注意的快照细节invalid(27)invalid(30)展示了 TypeScript 场景下的自动修复包括const array: string[] []、元组[string]、Int8Array类型标注以及通过declare function getBytes(): Int8Array提供的类型信息解析——带类型信息的接收者同样可以被修复。3.2 非箭头函数回调双建议并行当回调是普通函数表达式、具名函数表达式、标识符或as断言等无法确认是否使用this的形态时快照第二组invalid(1)invalid(26)规则同时提供两个建议见 getProblemRemove this argument.——直接删除thisArgUse a bound function.——将回调改写为callback.bind(thisArgument)。快照invalid(1)第二组完整展示了双建议的输出输入 array.map(callback, thisArgument) 建议 1/2 array.map(callback) 建议 2/2 array.map(callback.bind(thisArgument))对于函数表达式与具名函数表达式bind 建议同样适用快照invalid(7)、invalid(9)function () {}.bind(thisArgument)、function callback () {}.bind(thisArgument)。3.3 快照中未显示的深层分支从 规则源码 的useBoundFunction可以看到快照输出背后还有一层安全网生成 bind 建议时若回调是成员表达式对象如foo.bar且不加括号会被解析为foo.bar.bind(...)的错误语义会先自动补上括号快照invalid(12)第二组的array.map( foo as bar, (( thisArgument )),)输出(foo as bar).bind((( thisArgument )))正是这一逻辑的体现。此外thisArg若是逗号表达式(0, thisArgument)bind 建议会原样保留为callback.bind((0, thisArgument))快照第二组invalid(4)invalid(6)语义等价、格式安全。四、忽略与跳过避免误报的防线快照只能看到 invalid 用例规则的克制体现在 valid 用例与工具函数中。4.1 第三方库方法忽略列表规则内置了一个ignored列表rules/no-array-method-this-argument.js涵盖同名但语义不同的第三方 APILodash / Underscore_.every、_.filter、_.map、_.some、_.find、_.findLast、_.findIndex、_.findLastIndex、_.flatMap、_.forEachjQuery$.map、jQuery.map$.find、$.filter本就不接受第二实参测试中以 jQuery 选择器用例验证ReactReact.Children.map、Children.map、React.Children.forEach、Children.forEachRamdaR.map、R.filter、R.find、R.findIndex、R.forEach、R.findLastVueVue.filter。测试文件 中对应的 valid 用例如lodash.find(array, () {})、Vue.filter(capitalize, () {})印证了这些方法调用均不会触发报告。4.2 已知非数组接收者规则通过shouldSkipKnownNonArrayReceiverrules/utils/should-skip-known-non-array-receiver.js跳过已知不是数组的接收者Set、Map等非索引集合new Map().forEach(callback, thisArgument)合法测试 valid 用例TypeScript 类型感知下声明了同名方法的自定义类型如mapperService.map(firstError, errors[firstError])与this.service.find(dto, invoker)在类型检查下被正确跳过new Foo()非new Array()一律视为非数组——即使该类继承自Array也会被跳过源码注释明确说明这是有意为之。例外是类型化数组Int8Array等它们与Array共享大部分方法签名、同样接受thisArg因此foo.map(() {}, thisArgument)仍然会被报告快照第一组invalid(29)、invalid(30)。同时ArrayExpression、FunctionExpression、Literal、ObjectExpression、TemplateLiteral这类字面量形态的接收者总是被报告因为类型不匹配在调用点就能直接看出。4.3 回调非函数时的跳过若第一个实参经isNodeValueNotFunction判定不是函数如array.map(new Callback, thisArgument)、array.map(1, thisArgument)、await callback规则直接返回不报告测试 valid 用例见 test/no-array-method-this-argument.js。五、底层修复实现remove-argument 的边界处理快照中大量逗号、括号、尾随逗号用例背后是通用工具 rules/fix/remove-argument.js 中getArgumentRemovalRange的三分支区间计算唯一实参同时删除可能存在的尾随逗号fn(a,)→fn()首个实参一直删到后面的逗号及其后空白保证fn(a, b)修复为fn(b)而非fn( b)其余实参从前面那个逗号开始删fn(a, b)→fn(a)。这解释了快照中这些看似奇怪输入的修复结果输入修复输出快照位置array.map(() {}, thisArgument,)array.map(() {},)第一组invalid(16)array.map(() {}, (0, thisArgument),)array.map(() {},)第一组invalid(17)Array.fromAsync(iterableOrArrayLike, () {}, thisArgument,)Array.fromAsync(iterableOrArrayLike, () {},)第一组invalid(19)array.map( foo as bar, (( thisArgument )),)array.map( foo as bar,)第二组invalid(12)注意第一组invalid(16)与invalid(17)即使thisArg是(0, thisArgument)这样的逗号表达式只要整体无副作用依然被自动修复删除后保留尾部逗号——修复工具只做文本区间删除绝不重排参数格式从而把格式化职责留给 Prettier 等工具。当删除区间内含有注释且实参非末尾时removeArgument还会走replaceTextRange分支只剔除参数文本而保留注释见 remove-argument.js。六、快照测试如何阅读与使用这份报告test/snapshots/no-array-method-this-argument.js.md 是由 AVA 从 test/no-array-method-this-argument.js 的test.snapshot()用例自动生成的 Markdown 报告对应的二进制快照文件为 test/snapshots/no-array-method-this-argument.js.snap。它把每个 invalid 用例渲染成三部分Input原始被测代码含行号Message报告位置^精确指向thisArg实参与错误消息文本Output / Suggestion--fix的修复结果或编辑器可用的建议列表。读取时关注三条线索是否出现Output有 Output 表示该用例可自动修复箭头回调 无副作用只有 Suggestion 表示需要人工选择Suggestion 的数量1 条仅删除通常是副作用场景还是 2 条删除 bind完全没有修复输出说明删除会破坏注释或存在副作用规则选择只报告错误。当运行npx ava test/no-array-method-this-argument.js且规则行为与快照不一致时AVA 会提示快照不匹配若是有意的行为变更可在确认后更新快照。因此这份报告既是回归测试的证据链也是开发者理解规则到底会对哪些代码做什么的最直观参考。七、实战小结在项目中启用该规则no-array-method-this-argument已默认包含在recommended与unopinionated配置中见 docs/rules/no-array-method-this-argument.md。在项目里只需{ plugins: [unicorn], rules: { unicorn/no-array-method-this-argument: error } }启用后配合eslint --fix绝大多数箭头回调 无副作用thisArg的冗余实参会自动清除需要保留自定义this的普通函数回调则会在编辑器中得到删除参数或改为 bind两条建议供人工决策。最终效果是让thisArg这个易误解、易失效的隐藏参数从代码中消失换取更直白的闭包引用或显式绑定。核心参考文件规则实现rules/no-array-method-this-argument.js规则文档docs/rules/no-array-method-this-argument.md单元测试test/no-array-method-this-argument.js快照报告test/snapshots/no-array-method-this-argument.js.md参数删除工具rules/fix/remove-argument.js接收者类型判断rules/utils/should-skip-known-non-array-receiver.js【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表