我是编码初学者,我不知道如何处理“代码/函数结构问题”。因此,当您编写一个函数并且该函数开始具有更多从属函数时……我的意思是它开始成为一个多级函数,我不知道我应该如何构建我的代码以使其保持干净和可读。
这是一个示例代码,它是 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
,它在功能上更深入:declareWinner
、disableClickOnFields
、higlightAllFields
, declareWinnerOnModal
.
因此,当您在主函数的一个子函数中添加一层函数时,代码确实变得不可读、太长且难以抗拒。
当我开始写入我的主 app.js
文件时,我在想什么应该是主要的 Controller 。然后我不会再深入一个级别,我会导入我的第一级功能所需的所有必要功能。在这里,我将导入函数 gameOver
所需的所有函数。
但是我应该将所有全局变量和我在 gameOver
之上词法声明的所有其他变量传递给 gameOver
然后函数定义和调用将非常长丑陋的:gameOver(global1,global2,global3,global4,...)
我导入的函数无法访问父函数的变量对象,因此我应该再次将所有变量作为参数传递给第二级函数 - 以及从属函数 - 需要。
最佳答案
But then I should pass into 'gameOver' all of the global and every other variables which I declaired lexically above gameOver and then the functions definition and call would be a really long and ugly: (gameOver(global1,global2,global3,global4,....))
您可以引入一个包含所有全局变量的游戏“状态”:
const state = { global1, global2, global3, global4 };
然后你只需要将该状态传递给函数:
gameOver(state);
如果函数只需要一个或两个全局变量,它也可以解构对象:
function gameOver({global1, global2 }) {
console.log(global1);
}
So when you have lets say an additional layer of functions in one of the sub-functions in your main function the code really gets to be unreadable, too long and overwhelming.
函数的嵌套深度不应超过一层。其中一些函数可能是辅助函数,它们只能访问外部函数的一个或两个变量,因此您可以将它们作为参数传入。所以例如你可以把这个:
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);
关于javascript - 如何构建具有多级功能层的代码/功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50783411/