- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
在 JavaScript 中,值在布尔上下文中会被隐式转换(类型强制转换),因此几乎任何数组校验都可以归结为“判断一组值是否为真值(truthy)或假值(falsy)”。本文基于 30-seconds-of-code 仓库中的 check-array-values-are-truthy 文档,讲解如何利用Array.prototype.every()与Array.prototype.some()组合Boolean函数,实现“全部为真”“存在为真”“全部为假”以及“集合中所有对象均含某属性”四种常用校验,并给出可直接复制运行的代码与边界行为说明。读完本文,你将掌握一套零依赖、一行代码即可完成数组真值校验的实战方案。
前置概念:真值(truthy)与假值(falsy)
JavaScript 在条件判断等布尔上下文中会执行类型强制转换(type coercion),即把任意值隐式转换为布尔值。转换结果为true的值称为真值(truthy),结果为false的值称为假值(falsy)。完整规则详见仓库文档 truthy-falsy-values。
JavaScript 中只有 6 类假值:
| 假值 | 说明 |
|---|---|
false | 布尔关键字 |
undefined | 未定义原始值 |
null | 空值原始值 |
''、"" | 空字符串 |
NaN | 全局属性 NaN(非数值) |
0、-0、0.0、-0.0、0n | 表示 0 的数字或 BigInt |
除此之外的所有其他值都是真值,这一点容易踩坑:空数组[]、空对象{}虽然“看起来为空”,但它们在布尔上下文中求值均为true。
判断单个值的真假有两种等价写法:Boolean(value)或双重否定!!value。Boolean函数本身就是返回布尔值的函数,因此它天然适合作为数组方法的回调,这也是本文所有实现的基础。关于Boolean函数更多使用场景,可参考仓库文档 boolean-function。
注意:
new Boolean(false)这类Boolean对象永远是真值(对象包装器本身非空),因此请始终使用函数形式的Boolean(value),而不要用构造器创建 Boolean 对象。
检查数组中所有值是否为真值
要确认数组中每一个元素都为真值,使用Array.prototype.every()即可。every()会对每个元素执行回调,只有全部通过才返回true,遇到首个不通过的元素即短路返回false。
const all = (arr, fn = Boolean) => arr.every(fn); all([4, 2, 3], x => x > 1); // true all([1, 2, 3]); // true要点解析:
- 默认回调
Boolean:all([1, 2, 3])等价于[1, 2, 3].every(Boolean),将每个元素转换为布尔值判断真伪; - 自定义回调:第二参数
fn可以替换为任意谓词函数,例如x => x > 1。自定义回调会接收与every()相同的参数(当前值、索引、数组本身),因此可以编写任意复杂度的条件; - 空数组行为:
every()对空数组返回true(数学上的“空真”/vacuous truth),即all([])为true,意味着“空集合中的所有元素都满足条件”在逻辑上成立。底层行为可参考仓库文档 empty-array-every-some。
检查数组中是否存在真值
只需要“至少一个元素为真”时,改用Array.prototype.some()。some()遇到首个通过回调的元素即短路返回true,全部不通过才返回false。
const any = (arr, fn = Boolean) => arr.some(fn); any([0, 1, 2, 0], x => x >= 2); // true any([0, 0, 1, 0]); // true与all完全对称:默认使用Boolean判断真值,也可传入自定义谓词,如示例中判断是否存在不小于 2 的元素。需要注意some()对空数组返回false(不存在任何元素,自然“没有一个元素满足条件”),因此any([])为false,与every()的空数组行为恰好相反。
检查数组中所有值是否为假值
“没有任何元素为真”即“所有元素为假”。实现上可以复用some()并对结果取反:只要some()发现一个真值,取反后就得到false;只有全部为假时!arr.some(fn)才为true。
const none = (arr, fn = Boolean) => !arr.some(fn); none([0, 1, 3, 0], x => x == 2); // true none([0, 0, 0]); // true语义要点:
- 默认回调下,
none([0, 0, 0])检查的是“这三个元素全都是假值”,结果为true; - 自定义回调时,
none([0, 1, 3, 0], x => x == 2)等价于“不存在任何等于 2 的元素”,示例中数组确实没有2,故为true; - 空数组场景下,
none([])为!false即true——没有任何元素为真,符合“全部为假”的直观预期。
进阶:检查集合中所有对象是否都具有某属性
把every()的用法再推进一步,可以校验一个对象数组中的每个对象是否都拥有指定属性,这在数据合法性校验(例如表单提交前的字段完整性检查)中非常实用。实现只需通过属性名访问对象成员:属性存在则返回其值(真值),属性不存在则返回undefined(假值)。
const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]); truthCheckCollection( [ { user: 'Tinky-Winky', sex: 'male' }, { user: 'Dipsy', sex: 'male' }, ], 'sex' ); // true理解这个实现需要注意两点:
- 访问语义:
obj[pre]使用括号访问属性,若对象缺少该属性,返回undefined即假值,every()立即返回false; - 只校验存在性而非取值:即便属性值为
0、''、null等假值,也会被判定为“不具备该属性”,因此该方法适合“字段是否填写”级别的校验;若要校验属性值满足特定条件,可把回调改为obj => obj[pre] !== undefined或自定义谓词。
边界情况与最佳实践
空数组的三个结论
综合前文,把all/any/none作用于空数组[]的结果汇总如下:
| 工具函数 | 空数组结果 | 依据 |
|---|---|---|
all([]) | true | every()对空数组恒真(vacuously true) |
any([]) | false | some()对空数组恒假 |
none([]) | true | !some()对空数组取反 |
在真实的业务校验中,若需要把“空数组视为校验不通过”,应在使用all前单独判断arr.length === 0,这一点务必根据业务语义显式处理,不要依赖默认行为。
自定义回调的通用性
三个工具函数的核心设计是“默认回调Boolean,可选自定义谓词”,这让它们既可以直接做真值检查,也可以退化为通用的“全部满足 / 存在满足 / 均不满足”条件判定器。类似的组合模式在仓库中大量复用,例如 array-includes-any-or-all-values 用values.some(v => arr.includes(v))判断“包含任一值”、用values.every(v => arr.includes(v))判断“包含全部值”;all-values-of-array-are-equal 则用arr.every(val => val === arr[0])判断数组元素是否全部相等。
性能提示
every()与some()都是短路求值:every()在遇到首个false时停止遍历,some()在遇到首个true时停止遍历,因此它们通常不需要遍历整个数组。但若回调本身开销较大(如逐元素访问远程数据),仍需评估整体成本;对“判断是否包含某些值”这类场景,仓库文档建议大数组下改用Set提升性能。
仓库中的历史与定位
当前文章对应的工具函数在项目演进中经历过多轮整合,redirects.yaml 中保留了完整的历史映射记录(301 重定向),可见本文是多个独立片段的合并成果:
/js/s/all、/js/s/all-array-elements-are-truthy→ 本文“全部为真”部分/js/s/any、/js/s/any-array-element-is-truthy→ 本文“存在为真”部分/js/s/none、/js/s/all-array-elements-are-falsy→ 本文“全部为假”部分/js/s/truth-check-collection→ 本文“对象属性校验”部分
这说明“数组真值检查”在 JavaScript 开发中是高频且被反复拆解组合的经典需求。作为 30-seconds-of-code 的 JavaScript 片段之一,它被收录于 javascript 语言目录 并归类到 array、logic、object 等标签,读者可以在仓库的 js 集合索引 中找到与之相邻的数组操作片段,形成完整的知识脉络。
小结
本文给出了四个可直接复用的工具函数,覆盖数组真值检查的全部核心场景:
// 全部为真 const all = (arr, fn = Boolean) => arr.every(fn); // 存在为真 const any = (arr, fn = Boolean) => arr.some(fn); // 全部为假(不存在为真) const none = (arr, fn = Boolean) => !arr.some(fn); // 所有对象均具有某属性 const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]);它们的共同点是:以Boolean作为默认回调实现真值判断,同时开放自定义谓词参数以覆盖更复杂的业务条件。使用时请牢记三点边界:空数组下every()恒真、some()恒假;Boolean对象包装器恒真应避免使用;truthCheckCollection仅校验属性存在性而非属性值本身。将以上代码与语义结合进你的项目,即可获得轻量、无依赖且可读性良好的数组校验工具。
- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
相关推荐
30 Seconds of Code:用 `some`、`every` 与 `includes` 检查 JavaScript 数组是否包含任意值或全部值
30 Seconds of Code:用 some 、 every 与 includes 检查 JavaScript 数组是否包含任意值或全部值 在 JavaS
教程文档30-seconds-of-interviews 面试题精讲:JavaScript 真值与假值(Truthy and Falsy Values)完全指南
30 seconds of interviews 面试题精讲:JavaScript 真值与假值(Truthy and Falsy Values)完全指南 导读
教程前端30-seconds-of-code 实战:如何用 JavaScript 检查数组是否包含某个值(基础值与对象)
30 seconds of code 实战:如何用 JavaScript 检查数组是否包含某个值(基础值与对象) Array.prototype.include
教程文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考