Switch Statement "Memory?" "Informally" Looping a Switch Statement


#1

Does the switch statement have some kind of “memory” in the below “informal” (not an explicit for or while) loop – or is it something particular to (and peculiar about!) my code?

function toDo() {
	var userInput = prompt("What would you like to do?\n\nType:\n\"New\" to add a To-Do\n\"List\" to view the To-Do List\n\"Quit\" to exit this program");
	switch (userInput) {
		case "new":
			alert("newing!");
			toDo();
		case "list":
			alert("listing!");
			toDo();
		case "quit":
			alert("Quitting!");
			break;
		default:
			userInput = prompt("Please choose \"New,\" \"List,\" or \"Quit:\"");
	}
}

toDo();

On the first pass, no matter the option typed in, this code always runs fine…but if an option other than Quit is selected, then Quit never works right; for example:

  1. List, then Quit, results in case "quit" being run twice before exiting the program; List, List, then Quit results in it being run thrice before exiting; List, List, List, then Quit results in it being run four times…and so on.
  2. New, then Quit, however, results in case "new" being run and then case "list" – before running the whole function again, prompting for input as initially…try to Quit again and case "quit" runs twice before finally exiting the program.

Now all that repetition that makes me wonder whether something is being “remembered”…anyone know what’s going on in the logic?

Incidentally, is there a way for default to capture and pass along the value in its prompt()? As it is, it does nothing but seeming to prompt for input but whatever’s entered isn’t passed along and I can’t imagine how to do so…

Much obliged!!


The "Cancel" Button of an Alert or Prompt
#2

BTW, just so y’all know that I’ve done my due diligence on this: I’ve even used Chrome’s debugger command in the console to see what’s going on (substituting console.log() for all the alert() to make things easier) but I see nothing I didn’t know before – the debugger runs 1) and 2) without providing any insight (not that I really know how to use the Chrome debugger, to be sure)…


#3

It took me a sec to find the problem. The switch is not remembering what you typed in.
The problem here is that each case needs a break else the switch statement thinks that the next case is still part of itself. This makes for unexpected behavior.

function toDo() {
	var userInput  = null;
	userInput = prompt("What would you like to do?\n\nType:\n\"New\" to add a To-Do\n\"List\" to view the To-Do List\n\"Quit\" to exit this program");
	switch (userInput) {
		case "new":
			alert("newing!");
			toDo();
			break;
		case "list":
			alert("listing!");
			toDo();
			break;
		case "quit":
			alert("Quitting!");
			break;
		default:
			userInput = prompt("Please choose \"New,\" \"List,\" or \"Quit:\"");
			break;
	}
	console.log(userInput)
}

this looks to be working more like expected. watch how i added the breaks on each case.

The output to console still only happens when you break from the function. since some cases calls itself this will only happen when quit is given as input.


#4

AAAAAAAAAAAAAAAUUGGH!!!

Thank you…I think I might have to do coffee on a habitual basis ('cause I can’t sleep for some reason these days but am always sleepy!!) for the first time in my life…making too many mistakes…why, just a few hours ago today I forgot to use $12 of coupons at the grocery and then proceeded to irrevocably trash the receipt!!!

Erm, anyway, thanks so much…good grief…"[only] a little knowledge is a dangerous thing!"


#5

What is the purpose of defining userInput = null?

No. It has no memory. Now you know what happens when we omit break. Remember an earlier statement about function calls returning to their call? In your opening post we can see that for new when toDo() returns the flow continues to list, and when toDo() returns flow continues to quit.

Personally, I am not in favor of ever getting user input inside a function the way you have it. Separate concerns by having a function to get userInput that only returns valid inputs else keep looping over the prompt(). When you have valid input, use it as an argument in a call to toDo().

Also, when using a switch in a function, return from each case and then you don’t need break

function toDo(choice) {
  switch (choice) {
    case "new": return new_task();
    case "list": return list_tasks();
    case "quit": return false;
  }
}

If you user input function is working correctly, there will never be a need for a default case.

Functions should be task oriented and not do too much. Their behavior should be predictable.

Lastly, if this topic does not relate to an actual lesson then it belongs in the general programming category.


#6

BTW, I remember now…that I had actually thought that no break; was necessary since JavaScript has been directed to the start of the function again (with each case’s toDo();)…then promptly forgot about it once my brain got scrambled by fear and yet another coding disappointment (I very very rarely get something right the first time around – even these simple things!!!)…but still, I do need sleep and/or coffee…!

Thanks again.


#7

Good catch!

I’ve just tested it in the Chrome console; seems to have no effect whatsoever on anything (as expected).


#8

null is an assignable value, whereas undefined is not, but the only real reason to assign it would be memory management. We cannot delete variables but we can make them give up their memory by setting them to null.

Something to know about prompt() is that if the user clicks Cancel or presses the Esc key the function will return null. This is how we know the user cancelled the input. Your input function should be testing for this result and have in place a way to exit the program or a fallback to prevent flow from going through code that expects that user input.


#9

Fascinating! “We cannot delete variables”…never even thought to! But now that raises the question: if variables aren’t “deleted,” don’t they therefore take up memory and isn’t that, like, “inefficient” or something?

You know, I never even thought of that! I just thought the browser handled it all – until I just very recently realized that it doesn’t, as per my question at The “Cancel” Button of an Alert or Prompt – so I’ll look into this…thanks!!!


#10

It’s called memory leakage and believe it or not that is and always has been a primary concern of the ECMAScript working group. The inefficiency is not on the shoulders of ES, though, but on the programmer. There are several ways to minimize memory wastage, functions being the front line. When we exit a function it gives all its memory back. The only memory we have to worry about is what is in global scope.

One of the tenets of good programming is, “Protect the global namespace”, and keep it clear of unused or little used objects. As I stated, setting a variable to null will give back all its memory. There is only one null object in existence and it is at the top of the prototype chain. Any variable set to null points to that location, as do all objects.

There is a busload of dry, technical reading out there. You could be at it for months, or even years. Still, put that on the back burner and focus your efforts on mastering the language concepts, then turn your attention to efficiency, but not before. It should be the last thing on one’s mind at this stage. Stick to basics and drill deep down into every little detail with repeated review and practice.