记忆游戏中setTimeout调用flipBack函数失效及TypeError报错问题求助
Hey Jake, let's get that card flip-back working properly! The error you're seeing is exactly what you suspected—here's the breakdown and fix:
The Root Problem
You’re clearing the latestTwoRevealedCards array right after calling setTimeout(flipBack, 5000). By the time the timeout runs 5 seconds later, that array is empty, so when flipBack tries to access latestTwoRevealedCards[i].style, it’s trying to read properties of undefined—hence the TypeError.
The Solution
We need to preserve the reference to the two revealed cards before clearing the main array. Here's how to adjust your code:
Step 1: Modify the Mismatch Logic
Instead of clearing latestTwoRevealedCards immediately, create a copy of the array to pass to flipBack. Use an anonymous function as the setTimeout callback to retain this reference:
else if (revealCounter == 0 && imgAltArray[0] !== imgAltArray[1]) { wrongGuesses++; fails.textContent = `Failed attempts: ${wrongGuesses}`; // Create a copy of the currently revealed cards const cardsToFlipBack = [...latestTwoRevealedCards]; // Reset your tracking variables right away imgAltArray = []; latestTwoRevealedCards = []; revealCounter = 2; // Pass the copied array to flipBack in the timeout callback setTimeout(() => flipBack(cardsToFlipBack), 1500); // 1.5s is more user-friendly than 5s! }
Step 2: Update the flipBack Function
Modify flipBack to accept the copied array of cards as a parameter, so it doesn’t rely on the now-cleared global array:
function flipBack(cardsToFlip) { for (const card of cardsToFlip) { card.style.visibility = "hidden"; } }
Why This Works
By creating cardsToFlipBack with the spread operator ([...latestTwoRevealedCards]), we make a snapshot of the two cards that need to be flipped back. Even though we reset the global latestTwoRevealedCards array immediately, the timeout callback still holds onto this snapshot, so flipBack has valid card elements to work with when it runs.
Bonus Tips for Polish
- Prevent duplicate clicks: Add a check in
revealCardto make sure users can’t click the same card twice in a turn. For example:function revealCard(event) { let cardImg = event.target.firstChild; // Don't let users flip an already revealed card if (cardImg.style.visibility === "visible") return; // Rest of your existing logic... } - Adjust delay time: 5 seconds is quite long for a memory game—1-2 seconds is usually enough for users to register the second card.
内容的提问来源于stack exchange,提问作者JakeRedgrave

