JS OOP开发返回对象类型错误与测试报错排查
问题根因
所有报错都来自基础语法和逻辑疏漏,和OOP、TDD范式本身无关,一共5处明确错误:
- 语法拼写错误:
Game.js第一行引入Character时,const关键字漏写首字母c,写成了onst,会直接触发语法报错;deleteCharacter方法中读取角色数组时写的是this.character[i],正确属性名是this.characters,这是TypeError: Cannot read properties of undefined (reading '0')的直接原因——不存在的属性值为undefined,按下标读取自然报错。 createCharacter返回值逻辑错误:每次新角色push进数组后,固定返回this.characters[0],如果创建多个角色,永远返回第一个创建的实例,不会返回当前新建的对象。- 遍历逻辑错误:
findCharacter、deleteCharacter的for循环中写了else分支,只要第一个元素不匹配搜索值,就直接返回“未找到”,完全不会遍历后续数组元素。 - 数组方法使用错误:
deleteCharacter中splice第一个参数要求传入删除起始位置的下标,代码里直接传入了角色对象本身,会被隐式转换为NaN,删除逻辑完全失效。 - 测试断言匹配问题:用
toEqual对比Character类实例和普通对象字面量时,部分测试框架会识别实例的类标签,抛出“预期为普通Object,实际为Character实例”的类型错误。
修正后代码
src/character.js
class Character { constructor(characterName, characterAge) { this.characterName = characterName this.characterAge = characterAge this.health = 100 // 注意:此处保留原代码的invintory拼写(正确拼写为inventory),避免和现有逻辑不匹配 this.invintory = [] this.weapons = [] } } module.exports = Character
src/Game.js
const Character = require('./character') class Game { constructor() { this.characters = [] } createCharacter(characterName, characterAge) { const character = new Character(characterName, characterAge) this.characters.push(character) console.log('char = ', character) // 直接返回刚创建的实例,不要写死取数组第一个元素 return character } findCharacter(searchName) { for (let i = 0; i < this.characters.length; i++) { if (this.characters[i].characterName === searchName) { return this.characters[i] } } // 全量遍历完成未找到匹配项,再返回错误提示 return 'Error! Character not found!' } showAllCharacters() { return this.characters } deleteCharacter(searchName) { for (let i = 0; i < this.characters.length; i++) { // 修正属性名拼写 if (this.characters[i].characterName === searchName) { // splice传入匹配元素的下标i this.characters.splice(i, 1) return 'Player deleted' } } // 全量遍历完成未找到匹配项,再返回错误提示 return 'Player Not Found' } } module.exports = Game
测试用例修正
const Character = require('../src/character') const Game = require('../src/Game') describe('Jurrasic World ', () => { let game beforeEach(function () { game = new Game() }) it('create a new character', () => { // 预期值直接创建Character实例,避免类型匹配问题 const expectedResult = new Character('Dr Alan Grant', 42) const result = game.createCharacter('Dr Alan Grant', 42) expect(result).toEqual(expectedResult) // 如果不想用实例做对比,也可以用expect(result).toMatchObject({/* 属性键值对 */})做结构匹配 }) it('delete character by name', () => { const expectedResult = 'Player deleted' game.createCharacter('Dr Alan Grant', 42) const result = game.deleteCharacter('Dr Alan Grant') expect(result).toEqual(expectedResult) expect(game.characters).toEqual([]) }) })
额外提示:原代码中表示“背包”的
invintory为拼写错误,正确拼写为inventory,后续功能扩展前建议统一修正,避免多处拼写不一致导致的匹配问题。
内容的提问来源于stack exchange,提问作者user17511401
相关产品推荐
相关产品推荐

