JS OOP中Ship类构造函数调用addShip报错求助
解决Ship构造函数调用addShip时的TypeError问题
问题根源
你已经准确定位了报错原因:测试代码创建Itinerary时传入了二维数组[[port]],导致itinerary.ports成为嵌套数组,itinerary.ports[0]实际是一个数组而非Port类实例。数组没有addShip方法,因此调用this.currentPort.addShip(this)时抛出TypeError。
解决方案
1. 修复测试代码的数组传入错误
将测试中Itinerary的参数从二维数组改为一维数组,确保itinerary.ports直接存放Port实例:
describe("Ship", () => { it('can be instantiated', () => { const port = new Port ('Dover'); const itinerary = new Itinerary([port]) // 移除嵌套的外层数组 const ship = new Ship(itinerary) expect(ship).toBeInstanceOf(Object) }) })
修改后itinerary.ports[0]将正确指向Port实例,addShip方法可正常执行,测试即可通过。
2. 给Ship类添加防御性校验(可选但推荐)
为避免后续传入非法格式的Itinerary,可在Ship构造函数中增加合法性校验,提前拦截错误:
class Ship{ constructor(itinerary){ // 校验行程及港口的合法性 if (!itinerary?.ports?.length || !(itinerary.ports[0] instanceof Port)) { throw new Error('无效行程:必须包含至少一个Port实例'); } this.itinerary = itinerary; this.currentPort = itinerary.ports[0]; this.previousPort = null; this.currentPort.addShip(this); } // 原setSail、dock方法保持不变 }
后续若再传入错误格式的行程,会直接抛出明确的错误提示,便于快速排查问题。
额外优化:修复Port类的removeShip方法
注意到Port类的removeShip方法存在逻辑错误:pop()方法不接受参数,只会删除数组最后一个元素,无法移除指定船舶。建议修改为:
class Port { // 原构造函数、addShip方法保持不变 removeShip(ship){ if(ship){ // 过滤掉目标船舶,返回新数组 this.ships = this.ships.filter(s => s !== ship); // 或用splice实现: // const shipIndex = this.ships.indexOf(ship); // if (shipIndex !== -1) this.ships.splice(shipIndex, 1); } } }
内容的提问来源于stack exchange,提问作者Erdem_Ayhan
相关产品推荐
相关产品推荐

