What the code is supposed to do
The program greets three students and then announces the start of the class. The expected output has the three greetings first and the announcement once, at the end:
Hey, Andy
Hey, Mike
Hey, Mary
Let's start the class!
The code you start with produces the announcement after every greeting instead:
const students: string[] = ["Andy", "Mike", "Mary"];
for (const student of students) {
console.log("Hey, " + student);
console.log("Let's start the class!");
}
Hey, Andy
Let's start the class!
Hey, Mike
Let's start the class!
Hey, Mary
Let's start the class!
What goes wrong
This is the mirror image of putting a once-only line before a loop. The announcement sits between the loop's braces, so it is part of the body, and the body runs once for each of the three students. Each pass prints a greeting and then the announcement, which produces the alternating output.
It helps to ask of each line: how many times should this happen? The greeting depends on the current student, so it happens three times. The announcement is about the whole class, and it should happen one time, when all the greetings are done. A line that should run once, after the work of the loop is finished, belongs after the closing brace.
Fixing it step by step
- Keep the greeting in the body. It uses
student, so it must stay inside the loop. - Close the loop right after the greeting. Move the closing brace up, so that the body holds one statement.
- Put the announcement below the closing brace. It then runs once, as soon as the loop has handled the last student.
The fixed code in TypeScript
const students: string[] = ["Andy", "Mike", "Mary"];
for (const student of students) {
console.log("Hey, " + student);
}
console.log("Let's start the class!");
This prints the four expected lines:
Hey, Andy
Hey, Mike
Hey, Mary
Let's start the class!
A few notes on the code itself:
- The blank line is only for readers. TypeScript ignores it. What separates the loop from the final statement is the closing brace.
- Indentation shows structure, braces create it. Writing the announcement without indentation but before the closing brace would still keep it inside the loop. Move the brace, not just the whitespace.
constis fine for the loop variable. Each pass givesstudenta new value without reassigning one variable, so no error occurs.
Tracing the fixed program
Following the flow by hand is the best way to be sure of a fix. After the array is created, the loop starts:
studentis"Andy": the body printsHey, Andy, and the loop goes back to the header.studentis"Mike": it printsHey, Mike.studentis"Mary": it printsHey, Mary.- The array has no more elements, so the loop ends and the flow continues with the next line after the closing brace, which prints the announcement.
With the original code, the body in steps 1 to 3 also contained the announcement, which is why it showed up three times.
Common mistakes
- Only removing the indentation. If you un-indent the announcement but leave the closing brace below it, the line is still in the body, and the output does not change.
- Moving the announcement above the loop. It would print once, but first, and the class would start before anyone is greeted.
- Using
studentafter the loop. The variable exists only inside the loop. A line after the closing brace that mentionsstudentfails with aReferenceError. - Removing the announcement by accident. After moving things around, check that the last line is still there.
Checking your fix
Run the code in the editor above. The announcement should be the last line of the output and appear only once. Counting how many times each line appears is a quick check: three greetings, one announcement.