如何在类构造函数中实现跟踪对象?递归统计与计时问题排查
解决二进制数独生成器的统计计数错误与计时问题
一、修复Cannot read properties of undefined错误
问题根源是递归函数中的this指向丢失,递归调用时函数执行上下文改变,导致this.stats无法访问到类实例的属性。
方案1:构造函数中绑定函数this
在类的构造函数内,将每个递归函数的this绑定到当前实例:
constructor() { this.stats = { rowGenerator: 0, rowAssembler: 0, colTotalCheck: 0, colUniqueCheck: 0, runtime: 0 }; // 绑定递归函数的this到实例 this.rowGenerator = this.rowGenerator.bind(this); this.rowAssembler = this.rowAssembler.bind(this); this.colTotalCheck = this.colTotalCheck.bind(this); this.colUniqueCheck = this.colUniqueCheck.bind(this); }
方案2:用箭头函数定义递归函数
箭头函数会继承外层作用域的this,无需额外绑定即可指向类实例:
// 类内递归函数改用箭头函数定义 rowGenerator = () => { this.stats.rowGenerator++; // 递归逻辑代码... }; rowAssembler = () => { this.stats.rowAssembler++; // 递归逻辑代码... }; colTotalCheck = () => { this.stats.colTotalCheck++; // 递归逻辑代码... }; colUniqueCheck = () => { this.stats.colUniqueCheck++; // 递归逻辑代码... };
二、修复计时始终显示0ms的问题
当前计时逻辑的核心问题是:totalTime方法中同时获取开始和结束时间,两个时间点间隔可以忽略;且没有在递归执行前后分别记录时间节点。
修改计时代码:
constructor() { this.stats = { rowGenerator: 0, rowAssembler: 0, colTotalCheck: 0, colUniqueCheck: 0, runtime: 0 }; // 新增计时属性存储时间戳 this.startTimestamp = 0; this.endTimestamp = 0; } startTime() { // 记录递归开始前的时间戳 this.startTimestamp = performance.now(); }; endTime() { // 记录递归结束后的时间戳 this.endTimestamp = performance.now(); }; totalTime() { const duration = this.endTimestamp - this.startTimestamp; this.stats.runtime = duration; // 将时长存入统计对象 return `Runtime: ${duration.toFixed(2)}ms`; // 保留两位小数提升精度 };
正确使用方式:
在生成棋盘的主流程中按顺序调用:
generateBoard() { this.startTime(); // 递归前启动计时 // 执行完整的递归生成链 this.rowGenerator(); // ...其他递归调用 this.endTime(); // 递归结束后停止计时 console.log(this.totalTime()); // 输出运行时长 console.log(this.stats); // 输出各函数调用次数统计 }
内容的提问来源于stack exchange,提问作者Neuroneer
相关产品推荐
相关产品推荐

