我是编码的初学者,我无法弄清楚如何处理'代码/功能结构问题'。所以当你编写一个函数并且函数开始有更多的从属函数时...我的意思是它开始是一个多级函数,我不知道我应该如何构造我的代码,它仍然是干净和可读的。< / p>
以下是一个示例代码,它是tic-tac-toe game
的一部分
function gameOver(gameWonObj) {
if (gameWonObj === 'tie') {
higlightAllFields();
disableClickOnFields();
declaireWinner('tie');
} else {
highlightWinningHits();
disableClickOnFields();
declaireWinner(gameWonObj.player);
}
function higlightAllFields() {
allSquaresIds = ORIG_BOARD;
for ([idOfSquare, currValue] of allSquaresIds.entries()) {
currSquare = document.getElementById(idOfSquare);
currSquare.style.backgroundColor = TIE_COLOR;
}
}
function highlightWinningHits() {
winningSquaresIds = WIN_COMBOS[gameWonObj.index];
highlightColor = (gameWonObj.player === HU_PLAYERS_SIGN) ? WINNER_COLOR : LOOSER_COLOR;
winningSquaresIds.forEach(currentId => {
currentWinningSquare = document.getElementById(currentId);
currentWinningSquare.style.backgroundColor = highlightColor;
});
}
function disableClickOnFields() {
CELLS.forEach(cell => {
cell.removeEventListener('click', turnClick, false)
})
}
function declaireWinner(player) {
if (player === 'tie') {
declaireWinnerOnModal('ITS A TIE GAME', 'blue')
} else if (player === HU_PLAYERS_SIGN) {
declaireWinnerOnModal('YOU WON', 'lightgreen')
} else if (player === AI_PLAYERS_SIGN) {
declaireWinnerOnModal('AI WON', 'red')
}
function declaireWinnerOnModal(message, textColor) {
END_GAME_MODAL.style.display = 'block';
END_GAME_MODAL.style.color = textColor;
END_GAME_MODAL.innerHTML = `<p>${message}</p>`;
}
}
}
在这个示例中,我有一个主要功能:gameOver
,它在功能方面更深入:declaireWinner
,disableClickOnFields
,higlightAllFields
,{{1} }。
因此,当你在主函数的一个子函数中说一个额外的函数层时,代码真的变得不可读,太长而且压倒性。
当我开始写入我的主declaireWinnerOnModal
文件时,我正在思考什么应该是主要的主体。然后我不会更深入一级,我将导入我的第一级功能所需的所有必要功能。在这里,我将导入函数app.js
所需的所有函数。
但是我应该将gameOver
传递给gameOver
以上所有我在le gameOver
之上声明的全局和其他变量,然后函数定义和调用将会非常冗长和丑陋:{{1 }}
我导入的函数不能访问父函数的变量对象,因此我应该再次作为参数传递所有变量,其中第二级函数 - 以及次级函数 - 需要。
答案 0 :(得分:0)
然后我应该进入游戏“游戏”。所有全局变量和其他变量我在gameOver上声明了词法,然后函数定义和调用将是一个非常漫长和丑陋的:( gameOver(global1,global2,global3,global4,....))
你可以介绍一个游戏&#34; state&#34;包含所有全局变量:
const state = { global1, global2, global3, global4 };
然后你只需要将该状态传递给函数:
gameOver(state);
如果对象只需要一个或两个全局变量,该函数也可以对对象进行解构:
function gameOver({global1, global2 }) {
console.log(global1);
}
因此,当你在主函数的一个子函数中让一个额外的函数层时,代码真的变得不可读,太长而且势不可挡。
您不应该嵌套深度超过一个级别的函数。其中一些函数可能是帮助器,只访问thr外部函数的一个或两个变量,因此您可以将它们作为参数传递。例如,您可以将其转为:
function disableClickOnFields() {
CELLS.forEach(cell => { // Global?!
cell.removeEventListener('click', turnClick, false) // another global?!
})
}
分为:
/* Removes the listener on the specific event from all elements of thr collection */
function removeEventListener(collection, evt, listener) {
for(const el of collection) {
el.removeEventListener(evt, listener, false);
}
}
然后可以在多个位置重复使用,并且状态可以轻松传递:
removeEventListener(state.cells, "click", handleClick);