Lodash 源码阅读-createSet
概述
createSet
是 Lodash 中的一个私有工具函数,用于创建 ES6 的 Set 对象,它内部包含了对浏览器兼容性的检测,确保即使在不支持或有缺陷的环境中也能优雅降级。
前置学习
setToArray
:将 Set 对象转换为数组的辅助函数noop
:一个空函数,不执行任何操作Set
:ES6 提供的集合数据结构,存储唯一值
源码实现
javascript
var createSet = !(Set && 1 / setToArray(new Set([, -0]))[1] == INFINITY)
? noop
: function (values) {
return new Set(values);
};
实现思路
createSet
函数通过一个巧妙的检测来判断当前环境中 Set 的实现是否能正确处理特殊值(如-0)。如果检测通过,则返回一个可以创建 Set 的函数;如果失败,则返回一个空操作函数noop
,表示不支持该功能。
源码解析
兼容性检测
javascript
!(Set && 1 / setToArray(new Set([, -0]))[1] == INFINITY);
这行代码是整个函数实现的关键部分,它进行了一系列检测:
- 首先检查全局环境中是否存在
Set
构造函数 - 创建一个包含逗号(undefined)和-0 的数组
[,−0]
- 将该数组传入
new Set()
创建一个集合 - 使用
setToArray
函数将 Set 转回数组 - 访问结果数组的第二个元素(索引 1)
- 对该元素应用
1 / value
操作 - 检查结果是否等于
INFINITY
(即 Infinity 常量)
这个检测的巧妙之处在于,JavaScript 中1 / -0
会得到-Infinity
,而1 / 0
会得到Infinity
。通过这个特性,可以检测 Set 是否正确保留了-0 的符号。如果 Set 实现有问题,可能会丢失负号,导致检测失败。
条件判断
如果兼容性检测通过,则创建一个简单的函数来封装 Set 构造:
javascript
function(values) {
return new Set(values);
}
这个函数接收一个 values 参数(通常是数组),并返回一个包含这些值的新 Set 对象。
如果检测失败,则返回noop
函数:
javascript
function noop() {
// No operation performed.
}
noop
是一个空函数,不执行任何操作,这是一种优雅降级的方式。
总结
createSet
函数展示了 Lodash 处理兼容性问题的一种优雅方式:
- 针对可能有问题的 API 进行精确的特性检测
- 根据检测结果提供恰当的功能实现或降级方案
- 利用 JavaScript 中的特殊值(如-0、Infinity)进行巧妙的检测
这种方法确保了在不同环境中,Lodash 能够稳定可靠地运行,同时最大限度地利用现代 JavaScript 特性。从工程实践角度看,这种特性检测比简单的版本检测更可靠,因为它关注的是实际功能而非版本号。