One of my friends is teaching a programming class with Javascript and one of his assignments was to create a number guessing game. This was his example implementation:
funProgram: for(;;) {
numberGuesser: {
var num = (Math.random() * 100) | 0;
var guess = +prompt("I'm thinking of a number between 0 and 100. Try to guess it.", 0);
var guesses = 1;
guess: for(;;) {
higher: {
lower: {
if(guess === num) break guess;
if(guess > num) break lower;
guess = +prompt("Too low. Try again.", 0);
break higher;
}
guess = +prompt("Too high. Try again.", 0);
}
guesses++;
}
alert("You got it in " + guesses + " guesses! The number is " + num);
}
var again = prompt("Do you want to guess again (y/n)?", "y") === "y";
if(!again) break funProgram;
}
He told me that it's a good practice to label your code and wrap blocks around it so you can easily see what each section is doing. He also said labeled breaks and continues are much easier to read than unlabeled ones because you can know exactly what you are breaking out of. I've never seen any code patterns like this, so I'm not sure if this is true.
I've been using Javascript for a while and there are a few things in here that I've never seen before and some things that I still don't understand. I thought that the break
keyword was specifically meant for breaking out of loops. The higher
and lower
blocks are not loops, but apparently you can still break out of it. How is that possible? It seems odd to me to break out of something that doesn't loop. Can you also break out of functions using the break
keyword?
Breaks can in fact have labels (and do so accept them). However, I'm not sure who "He" is, but I would go as far as to say "He" is conveying his ideals of programming, rather than a specific standard. That is to say, there's no need to use labels, it just makes it more legible to that particular person. (And, IMHO, labels are reminiscent of the BASIC/GOTO days which usually results in Spaghetti Code).
Extra Credit: Ask your friend if they used to write in BASIC; I'm betting you'll get a "yes" (along with a lot of bad habits for the duration of the course--that's not to profile, I've just never had a good experience with BASIC/VB programmers following [current] coding patterns))
The break
command is commonly used to exit loops, however if the code block is nested within a label, you're establishing yet another block which you can break from. It also gives you a bit more flexibility as to where the break is meant to exit from. For example:
for (;;){ // "for a"
for(;;){ // "for b"
break; // breaks "for b"
}
}
In this instance, break
is only meant to exit the nested ("for b") loop. However:
myblock: {
for(;;){
for(;;){
break mybock; // breaks label "myblock"
}
}
}
In this case, break is actually exiting both loops because you're instructing it to quit the label block entirely. This would be almost like having:
function myblock(){
for(;;){
for(;;){
return; // exits function "myblock"
}
}
}
Where return
exits the block similar to the way break myblock
acts.
By the way, not for nothing, I find this a tad easier to read:
var again = true;
while (again){
var num = (new Date()).getMilliseconds() % 100,
guess = +prompt("I'm thinking of a number between 0 and 100. Try to guess it.", "1"),
guesses = 1;
while (num !== guess){
guesses++;
guess = +prompt((guess < num ? "Too low." : "Too high.") + " Try again.", guess);
}
alert("You got it in " + guesses + " guesses! The number is " + num);
again = prompt("Do you want to guess again? (y/n)", "y") == "y";
}