JavaScript 断言函数的奇妙冒险:手搓一个极简版 Jest 的 expect
一、需求分析:当法官的代码人生
最近在刷 LeetCode 时遇到了一个有趣的题目(),要求我们实现一个 expect 函数。这让我想起了测试框架中的断言功能——就像代码世界的法官,时刻准备敲下正义的小锤子:
function expect(val) {
return {
toBe: (target) => {
if (val === target) return true
throw new Error("Not Equal")
},
notToBe: (target) => {
if (val !== target) return true
throw new Error("Equal")
}
}
}
二、技术解剖:闭包的三重奏
1. 函数式编程的妙用
这个实现完美展现了 JavaScript 的函数式特性。expect 作为高阶函数,返回的对象方法共享着闭包中的 val——就像三个密谋的侦探共享关键线索。
2. 错误处理的艺术
当值不符合预期时,我们抛出错误而不是返回 false。这种设计参考了测试框架的常见做法,就像法官发现违法行为时不会悄悄记在本子上,而是直接敲锤宣判。
3. 类型安全的博弈
使用 === 和 !== 运算符确保了类型安全。试想如果用 ==,expect(0).toBe('') 就会成为漏网之鱼,就像用错法条的糊涂法官。
三、实战演练:当代码成为法庭
// 原告:数字5
const plaintiff = expect(5)
try {
// 被告A:数字5(当庭释放)
console.log(plaintiff.toBe(5)) // ✅
// 被告B:字符串'5'(当庭逮捕)
plaintiff.toBe('5') // 🚨 Error: Not Equal
} catch (e) {
console.error(e.message)
}
四、扩展思考:从玩具到工具
虽然这个实现很精妙,但与专业测试框架相比就像玩具水枪 VS 消防车。真正的 Jest 等框架还有这些超能力:
- 异步断言:能处理 Promise
- 自定义匹配器:
.toBeInstanceOf()、.toContain()等 - 错误追踪:精确到行号的堆栈信息
五、人生哲理:代码如人生
这个题目教会我们:
- 精确判断(===)比模糊认可(==)更重要
- 及时报错比沉默失败更有价值
- 函数闭包就像人际关系,共享的记忆造就独特的化学反应
下次当你的代码需要判断是非时,不妨试试这个手搓的「正义小锤子」吧!👨⚖️👩⚖️