一聚教程网:一个值得你收藏的教程网站

热门教程

JavaScript 中嵌套函数必须显式返回对象才能支持链式调用

时间:2026-06-24 09:56:51 编辑:袖梨 来源:一聚教程网

本文详解为何 expect(5).toBe(7) 报错 “Cannot read properties of undefined”,核心在于 expect 函数未返回包含 toBe 和 notToBe 方法的对象;通过修正返回值结构、使用严格相等(===)及正确异常处理,即可实现符合 LeetCode 要求的测试断言函数。

本文详解为何 `expect(5).tobe(7)` 报错 “cannot read properties of undefined”,核心在于 `expect` 函数未返回包含 `tobe` 和 `nottobe` 方法的对象;通过修正返回值结构、使用严格相等(`===`)及正确异常处理,即可实现符合 leetcode 要求的测试断言函数。

在 JavaScript 中,函数是一等公民,可以被声明、赋值、作为参数传递,也能作为返回值——但仅声明嵌套函数并不会自动将其暴露为可调用属性。题干明确要求:expect(val) 必须“返回一个包含 toBe 和 notToBe 两个函数的对象”。而你的原始代码中:

var expect = function(val) {  function toBe(val2) { /* ... */ }  function notToBe(val2) { /* ... */ }  // ❌ 缺少 return 语句 → 函数隐式返回 undefined};

因此 expect(5) 的结果是 undefined,后续调用 .toBe(7) 自然抛出 Cannot read properties of undefined (reading 'toBe')。

✅ 正确做法是:显式构造并返回一个对象,其属性为对应的方法。以下是两种推荐写法:

方式一:先定义函数,再解构返回(清晰易读)

const expect = function(val) {  const toBe = function(val2) {    if (val === val2) return true;    throw new Error("Not Equal");  };  const notToBe = function(val2) {    if (val !== val2) return true;    throw new Error("Equal");  };  return { toBe, notToBe }; // ✅ 返回含方法的对象};// 使用示例:console.log(expect(5).toBe(5));   // true// expect(5).toBe(7);            // throws Error: "Not Equal"console.log(expect(5).notToBe(3)); // true// expect(5).notToBe(5);         // throws Error: "Equal"

方式二:对象字面量内联方法(更简洁)

const expect = function(val) {  return {    toBe(val2) {      if (val === val2) return true;      throw new Error("Not Equal");    },    notToBe(val2) {      if (val !== val2) return true;      throw new Error("Equal");    }  };};

⚠️ 关键注意事项:

立即学习“Java免费学习笔记(深入)”;

  • 必须使用 ===(严格相等)而非 ==:题目明确要求 ===,避免类型转换导致误判(如 expect("5").toBe(5) 应返回 false);
  • 必须 throw Error,而非 return 字符串:题干要求“throw an error”,返回字符串 "Not Equal" 不会中断执行,也不符合测试框架惯例;
  • 不可省略 return:这是最常见新手疏漏——JS 函数默认返回 undefined,必须主动 return { toBe, notToBe };
  • 箭头函数需谨慎:若改用 const expect = (val) => ({ ... }),语法更简,但需确保对象外层括号完整,避免与函数体混淆。

总结来说,理解“函数返回对象,对象携带方法”这一模式,是掌握 JavaScript 链式 API(如 Promise.then().catch()、Jest 的 expect(...).toBe(...))的基础。不必纠结冷门语法符号(如冒号在对象方法中的作用),先夯实函数、对象、作用域和 this 的本质逻辑——这才是高效进阶的关键路径。

热门栏目