Chrome DevTools断点对作为方法调用的函数失效问题咨询
Chrome DevTools断点调试问题(Odin Project井字棋练习)
问题描述
我是编程新手,正在完成Odin Project的井字棋练习,遇到Chrome DevTools断点调试的问题:
- 在作为方法调用的函数处(例如第21行)设置断点,点击单元格后断点触发,但无法单步调试
checkIfWin()函数,直接执行完毕; - 在第105行设置断点则完全不生效。
目前只能通过在代码中写入debugger语句实现调试,想了解是否可以仅通过断点解决该问题。
相关代码
const gameBoard = (() => { const rowNumber = 3; const columnNumber = 3; const board = []; const boardContainer = document.querySelector('#board-container') const cell = (row, column) => { let value = 0 const cellRow = row; const cellColumn = column; const cellID = [cellRow, cellColumn] const renderCell = (cell) => { const cellDiv = document.createElement('div'); cellDiv.classList.add('board-cell') cellDiv.addEventListener('click', function(e) { let activePlayer = game.activePlayer if (getCellValue(cellRow, cellColumn) == 0) { updateCell(e.target, activePlayer) game.changeActivePlayer() game.checkIfWin(cellID) } }) boardContainer.appendChild(cellDiv) } const updateCell = (cell, player) => { cell.classList.add(player.color) gameBoard.board[cellRow][cellColumn].value = game.activePlayer.index } return {value, renderCell, updateCell, getCellValue} }; const getCellValue = (cellRow, cellColumn) => { return board[cellRow][cellColumn].value }; const changeCellValue = (cellRow, cellColumn, newValue) => { board[cellRow][cellColumn].value = newValue } const createBoard = () => { for (let i = 0 ; i < rowNumber ; i++) { board[i] = []; for (let j = 0 ; j < columnNumber ; j++) { const newCell = cell(i,j) newCell.renderCell() board[i].push(newCell) } } console.log('Create board se ejecuta') }; const getRow = (index) => { return board[index] } const getColumn = (index) => { let column = [] for (let i = 0 ; i < rowNumber; i++) { column.push(board[i][index]) } return column } const getDiagonal = (sign) => { let diagonal = [] for (let i = 0 ; i < rowNumber ; i++) { diagonal.push(board[i*(sign)][i*(sign)]) } return diagonal } return { board, createBoard, getCellValue, changeCellValue, cell, getRow, getColumn, getDiagonal, }; })(); const player = ((name, index, color) => { let score = 0 return {name, index, score, color}; }); const game = (() => { const player1 = player(prompt('Nombre de jugador 1'), 1, 'red') const player2 = player(prompt('Nombre de jugador 2'), 2, 'blue') let activePlayer = player1 const changeActivePlayer = () => { (game.activePlayer === player1) ? game.activePlayer = player2 : game.activePlayer = player1 } const checkIfWin = (cell) => { let row = gameBoard.getRow(cell[0]) let column = gameBoard.getColumn(cell[1]) const checkEqualValues = (line) => { let firstElement = line[0] for (let i = 0 ; i < line.length ; i++) { if (firstElement.value !== line[i].value) { return false } } return true } return checkEqualValues(row) || checkEqualValues(column) || checkEqualValues(gameBoard.getDiagonal(1)) || checkEqualValues(gameBoard.getDiagonal(-1)) ? console.log('alguien gano') : null } return { player1, player2, activePlayer, changeActivePlayer, checkIfWin, } })(); gameBoard.createBoard() game.changeActivePlayer()
问题解决办法
1. 第105行断点不生效的处理
第105行是game.checkIfWin(cellID)的调用,断点不生效主要是因为checkIfWin是IIFE(立即执行函数表达式)内部定义的函数,浏览器解析后行号可能和你看到的源码行号不匹配,或者DevTools没正确绑定到函数定义。
解决:直接找到checkIfWin的函数定义位置(代码中const checkIfWin = (cell) => {这一行),在Sources面板中定位到该行并设置断点,点击单元格触发时就会命中。
2. 无法单步调试checkIfWin()的处理
当在第21行断点触发后,无法步进函数是因为步进方式错误:
- 用「Step Into(快捷键F11)」而不是「Step Over(F10)」,F11会进入函数内部执行;
- 如果F11还是进不去,检查DevTools是否开启了「黑箱脚本」:在Sources面板的当前脚本上右键,取消勾选「Blackbox script」;
- 也可以在断点触发后,在右侧「Scope」面板找到
game.checkIfWin,右键选择「Show function definition」,跳转到函数定义处设置断点。
3. 通用断点调试技巧
- 在Sources面板顶部搜索
checkIfWin,快速定位函数定义位置; - 确保你在Sources面板中选择的是正确的脚本文件(如果是内嵌脚本,会显示在
(index)里;外部JS文件则选对应文件名)。
内容的提问来源于stack exchange,提问作者Julián Stramigioli
相关产品推荐
相关产品推荐

