Codepen迁移至Replit的JS函数调用checkColPlacement报undefined错误
数独求解函数迁移Replit后出现
this指向错误问题 问题描述
原在Codepen中运行正常的数独求解JavaScript函数,迁移到Replit后,在solve函数内调用checkColPlacement方法时抛出以下错误:
TypeError: Cannot read properties of undefined (reading ‘checkColPlacement’) at pencilArr (/home/runner/boilerplate-project-sudoku-solver/controllers/sudoku-solver.js:163:20)
- 但在
checkRegion函数中使用相同参数(puzzleString, "a", 1, 1)调用checkColPlacement能得到正确输出,仅solve函数内调用出现问题 - 已通过
console.log确认所有传入参数均已定义,点击项目的check按钮可正常运行相关检查函数,点击solve按钮触发报错
报错代码片段
solve(puzzleString) { let coordinate = ['a1','a2','a3','a4','a5','a6','a7','a8','a9','b1','b2','b3','b4','b5','b6','b7','b8','b9','c1','c2','c3','c4','c5','c6','c7','c8','c9','d1','d2','d3','d4','d5','d6','d7','d8','d9','e1','e2','e3','e4','e5','e6','e7','e8','e9','f1','f2','f3','f4','f5','f6','f7','f8','f9','g1','g2','g3','g4','g5','g6','g7','g8','g9','h1','h2','h3','h4','h5','h6','h7','h8','h9','i1','i2','i3','i4','i5','i6','i7','i8','i9'] /*pencilfunction*/ function pencilArr(puzzleString) { let pencil = [] for (let j = 0; j <= 80; j++) { pencil.push([]) if (puzzleString[j] != ".") { pencil[j].push("solved") pencil[j].push(puzzleString[j]) } else { for (let i = 1; i <= 9; i++) { console.log(puzzleString) console.log(coordinate[j][0]) console.log(coordinate[j][1]) console.log(i) console.log(this.checkColPlacement(puzzleString,"a",1, 1)) let pencilColumn = this.checkColPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i) let pencilRow = this.checkRowPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i) let pencilRegion = this.checkRegionPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i) if (pencilRegion != 'truebox' && pencilColumn != 'truecol' && pencilRow != 'truerow') { pencil[j].push(i) } } } } // 省略后续代码 } // 省略后续调用pencilArr的代码 }
问题原因
核心是内部函数pencilArr的this指向丢失:
checkColPlacement是SudokuSolver类的实例方法,需要通过类实例访问pencilArr是solve方法内部的普通函数,Replit/Node.js环境默认启用严格模式,普通函数调用时this为undefined- 而
checkRegion本身是类的实例方法,调用时this指向类实例,所以内部调用checkColPlacement时this指向正确
解决方案
以下三种方法任选其一即可:
方法1:提前保存类实例的this
在外层solve函数中先把类实例的this存到变量里,内部函数用这个变量代替this:
solve(puzzleString) { const self = this; // 保存类实例的this let coordinate = [...]; function pencilArr(puzzleString) { // ... let pencilColumn = self.checkColPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); let pencilRow = self.checkRowPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); let pencilRegion = self.checkRegionPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); // ... } // ... }
方法2:将pencilArr改为箭头函数
箭头函数的this继承自外层作用域的this,直接使用this即可访问类实例方法:
solve(puzzleString) { let coordinate = [...]; // 改成箭头函数 const pencilArr = (puzzleString) => { // ... let pencilColumn = this.checkColPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); let pencilRow = this.checkRowPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); let pencilRegion = this.checkRegionPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); // ... } // ... }
方法3:调用pencilArr时绑定this
在调用pencilArr的时候,用call或apply绑定类实例的this:
solve(puzzleString) { let coordinate = [...]; function pencilArr(puzzleString) { // ... let pencilColumn = this.checkColPlacement(puzzleString, coordinate[j][0], coordinate[j][1], i); // ... } // 调用时绑定this pencilArr.call(this, puzzleString); // 或者用apply:pencilArr.apply(this, [puzzleString]); }
内容的提问来源于stack exchange,提问作者crmarc
相关产品推荐
相关产品推荐

