资讯详情 collect.js 严格比较设计解析:未实现的 `*Strict` 方法与替代方案
📅 2026/10/15 23:04:44
开发工具【免费下载链接】collect.js Convenient and dependency free wrapper for working with arrays and objects项目地址https://gitcode.com/gh_mirrors/co/collect.js点击查看免费下载collect.js 是一个无依赖、专注于数组与对象操作便利性的 JavaScript 集合库。它的官方文档中专门列出了一份“未实现方法清单”bundler/not_implemented.md这份清单并非功能缺失而是设计取舍的直接体现collect.js 的所有比较默认采用严格相等因此 Laravel 中需要“严格变体”才能实现的语义在 collect.js 中本身就是默认行为。本文将以这份清单为骨架结合仓库源码与测试用例讲清每一个未实现方法的来龙去脉、底层原理以及迁移替代方案帮助你在实际项目中正确使用 collect.js 的集合查询能力。这份清单在项目中的位置与作用在深入内容之前先明确这份文档的“身份”。collect.js 的 README 并非手写维护而是通过 bundler/bundle.js 自动拼接生成它依次读取header、badges、installation、api、strictness_and_comparisons、not_implemented、contribute、license等 Markdown 片段并将docs/api/下每个方法的文档批量注入最终写出README.md。也就是说not_implemented.md与strictness_and_comparisons.md是官方 API 文档体系的组成部分位于 README 的“API 方法目录”与“方法详细文档”之间用于向使用者提前说明哪些 Laravel Collection 方法不会出现以及背后的比较语义。这两份文档是配套的bundler/strictness_and_comparisons.md 解释设计哲学bundler/not_implemented.md 列出受此影响而刻意不实现的 6 个方法。你可以在当前仓库的 README.md 中看到这两段的最终渲染形态“Strictness and comparisons”小节。核心背景collect.js 的比较哲学bundler/strictness_and_comparisons.md 原文如下全文仅两段但信息量很大All comparisons incollect.jsare done using strict equality. Using loose equality comparisons are generally frowned upon in JavaScript. Laravel only performs loose comparisons by default and offer several strict comparison methods. These methods have not been implemented incollect.jsbecause all methods are strict by default.翻译并拆解其含义collect.js 所有比较默认使用严格相等strict equality即/!语义类型不同即为不同。JavaScript 社区普遍不推荐宽松相等因为它会触发隐式类型转换带来难以排查的 Bug。Laravel Collection 默认是宽松比较例如100 100成立因此 Laravel 额外提供了containsStrict、whereStrict等一系列*Strict方法供需要严格语义的场景使用。collect.js 反其道而行既然全部方法默认就是严格的*Strict变体就失去了存在意义故不实现。理解这一点后not_implemented.md中的清单就顺理成章了。注意清单中每个方法名都带有删除线~~表示“已废弃/不提供”并明确指向替代方法containsStrict→ 使用contains()duplicatesStrict→ 使用duplicates()uniqueStrict→ 使用unique()whereStrict→ 使用where()whereInStrict→ 使用whereIn()whereNotInStrict→ 使用whereNotIn()未实现方法总览Laravel 方法collect.js 未实现collect.js 替代方法替代方法的严格语义依据containsStrictcontains()与indexOfsrc/methods/contains.jsduplicatesStrictduplicates()原始值严格同一性 引用型 JSON 序列化src/methods/duplicates.jsuniqueStrictunique()indexOf严格去重src/methods/unique.jswhereStrictwhere()默认运算符即src/methods/where.jswhereInStrictwhereIn()indexOf严格匹配src/methods/whereIn.jswhereNotInStrictwhereNotIn()indexOf严格匹配src/methods/whereNotIn.js下面逐一从源码与测试层面验证“替代方法天然就是严格的”。逐个解析为什么不需要*Strict方法containsStrict→contains()contains()用于判断集合是否包含某项其实现src/methods/contains.js在不同入参形态下全部走严格路径传入 key/value 对this.items[key] ! undefined this.items[key] value直接使用比较传入单个值数组集合使用Array.prototype.indexOf其本身就是严格相等语义传入回调函数交由调用者自定义判定传入单个值对象集合将对象的键与值合并后同样用indexOf查找。测试 test/methods/contains_test.js 精准验证了类型敏感性const collection collect({ name: Steven Gerrard, number: 8, }); collection.contains(number, 8); // false字符串 8 ≠ 数字 8 collection.contains(number, 8); // true这正是 LaravelcontainsStrict期望的语义——在 collect.js 中调用普通的contains()即可获得。duplicatesStrict→duplicates()duplicates()返回集合中重复出现的值src/methods/duplicates.js。其严格性体现在对原始值数字、字符串、null等直接放入occuredValues数组并用indexOf判定重复属于严格同一性比较对数组与对象先经JSON.stringify序列化后再比较避免“内容相同但引用不同”的误判。测试 test/methods/duplicates_test.js 覆盖了混合场景const collection collect([ 2, 2, [collect.js], [collect.js], collect([1, 2, 3]), collect([1, 2, 3]), ]); collection.duplicates().all(); // { 1: 2, 3: [collect.js], 5: collect([1, 2, 3]) }2与2严格相同被判重复两个内容一致的数组/集合对象也被识别为重复——这正是严格语义的体现无需单独的duplicatesStrict。uniqueStrict→unique()unique()返回集合中的唯一项src/methods/unique.js三种形态全部严格无参调用self.indexOf(element) index判定首次出现位置基于indexOf的严格相等按 key 去重用usedKeys.indexOf(uniqueKey)检查该 key 对应值是否已出现按回调去重回调返回值作为去重键同样走indexOf。测试 test/methods/unique_test.js 有一个非常直观的用例const collection collect([1, 1, 1, 2, 3, 3, 3]); collection.unique().all(); // [1, 2, 3, 3] —— 数字 3 与字符串 3 被视为不同项若按 Laravel 的宽松unique()语义3与3会被合并为一个collect.js 则保留两者等价于 Laravel 的uniqueStrict。whereStrict→where()where()是最能体现“默认严格”设计的方法。其实现src/methods/where.js支持多种运算符且二参数简写形式的默认运算符就是if (value undefined) { comparisonValue operator; comparisonOperator ; }也就是说where(price, 100)等价于where(price, , 100)只匹配数字100。测试 test/methods/where_test.js 的数据中有一个价格为字符串100的商品{ product: Door, price: 100 }观察两种写法的差异const collection collect([ { product: Desk, price: 200, manufacturer: IKEA }, { product: Chair, price: 100, manufacturer: Herman Miller }, { product: Bookcase, price: 150, manufacturer: IKEA }, { product: Door, price: 100 }, ]); collection.where(price, 100).all(); // 仅匹配 Chairstrict 默认字符串 100 被排除 collection.where(price, , 100).all(); // 匹配 Chair 与 Door显式宽松运算符100 100 成立where()支持完整运算符集、、!、、!、、、、并支持where(manufacturer)/where(manufacturer, true)/where(manufacturer, false)布尔简写以及通过 src/helpers/nestedValue.js 实现点号嵌套取值如where(foo.bar, 1)。由于默认即严格whereStrict没有必要存在需要宽松语义时反而要显式写出/!运算符。whereInStrict→whereIn()whereIn()按“key 的值是否在给定数组内”过滤src/methods/whereIn.js核心一行const collection this.items .filter(item items.indexOf(nestedValue(item, key)) ! -1);indexOf严格匹配因此[100]不会匹配值为字符串100的项。测试 test/methods/whereIn_test.js 同样使用Door: price 100验证whereIn(price, [100, 200])只返回Desk与Chair字符串100的Door被排除。此外该测试还证明第二个参数可以是普通数组也可以是另一个collect()集合两者行为一致。whereNotInStrict→whereNotIn()whereNotIn()是whereIn()的取反src/methods/whereNotIn.jsconst collection this.items .filter(item items.indexOf(nestedValue(item, key)) -1);同样基于indexOf严格匹配。测试 test/methods/whereNotIn_test.js 有一个反直觉但符合严格语义的用例const data [ { product: Desk, price: 200 }, { product: Chair, price: 100 }, { product: Bookcase, price: 150 }, { product: Door, price: 100 }, ]; collection.whereNotIn(price, [150, 200]).all(); // Chair(100)、Bookcase(150)、Door(100) // Bookcase 的 150数字不等于列表中的 150字符串因此未被排除若使用宽松语义150 150成立Bookcase会被误删collect.js 的严格默认避免了这类隐式转换陷阱。需要宽松比较时怎么办collect.js 的“默认严格”不等于“完全禁止宽松”。从源码看where()是唯一保留了宽松运算符的筛选方法先尝试 Number(comparisonValue)再尝试 comparisonValue.toString()即数字/字符串互相转换后比较!/对上述两者都否定其余运算符、!、、、、保持严格语义。因此从 Laravel 迁移时若业务确实依赖宽松匹配应显式改写为// Laravel$collection-where(price, 100)宽松 // collect.js需要宽松匹配时必须显式声明运算符 collection.where(price, , 100); // 需要严格匹配时两种写法等价 collection.where(price, , 100); collection.where(price, 100);而contains()、duplicates()、unique()、whereIn()、whereNotIn()没有宽松模式它们永远保持严格语义——这也正是*Strict版本“多余”的原因。从 Laravel 迁移到 collect.js 的对照速查原 Laravel 调用collect.js 等价写法containsStrict(key, value)contains(key, value)duplicatesStrict()duplicates()uniqueStrict(key)unique(key)whereStrict(key, value)where(key, value)即where(key, , value)whereInStrict(key, [..])whereIn(key, [..])whereNotInStrict(key, [..])whereNotIn(key, [..])where(key, value)宽松where(key, , value)迁移时注意两点去掉Strict后缀即可*Strict方法在 collect.js 中就是对应基础方法的默认行为无需额外 API反向留意宽松调用原本依赖 Laravel 宽松比较的where/whereIn/whereNotIn代码迁移后行为可能变化需要按上表显式加上运算符或调整数据格式。延伸阅读未实现清单与设计说明bundler/not_implemented.md、bundler/strictness_and_comparisons.md方法详细文档docs/api/contains.md、docs/api/duplicates.md、docs/api/unique.md、docs/api/where.md、docs/api/whereIn.md、docs/api/whereNotIn.md核心实现src/methods/contains.js、src/methods/duplicates.js、src/methods/unique.js、src/methods/where.js、src/methods/whereIn.js、src/methods/whereNotIn.js以及集合构造入口 src/index.js行为验证测试test/methods/contains_test.js、test/methods/duplicates_test.js、test/methods/unique_test.js、test/methods/where_test.js、test/methods/whereIn_test.js、test/methods/whereNotIn_test.js赞分享开发工具【免费下载链接】collect.js Convenient and dependency free wrapper for working with arrays and objects项目地址https://gitcode.com/gh_mirrors/co/collect.js点击查看免费下载相关推荐嫌订阅费肉疼5 款免费矢量设计工具够你用到下班嫌订阅费肉疼5 款免费矢量设计工具够你用到下班 上周接到一个改 Logo 的活儿打开软件才发现订阅已过期画布直接灰掉了。每月几十块的订阅费对刚接活的自由文档知识库nvim-lint替代方案比较与其他Neovim语法检查插件对比nvim lint替代方案比较与其他Neovim语法检查插件对比 当谈到Neovim语法检查插件时nvim lint是一个强大的选择但它并非唯一的选择。本开发工具代码质量Lintgorilla/websocket替代方案其他可选方案比较gorilla/websocket替代方案其他可选方案比较 概述 在Go语言的WebSocket生态中gorilla/websocket长期以来都是开发者的WebSocket后端网络通信创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考