Let me first admit that my class doesn’t always pay attention even when I announce that I am going to say something important.
I have noticed that var x = __; causes problems. It is itself a contraction of var x; and x = __; with the former being variable declaration and the latter being variable assignment. These are two very different concepts for our kids to tackle. In fact, Javascript hoisting often separates them without our knowledge.
Variable scope should be taught by itself independently of assignment. var x = __; makes that difficult. Good Javascript style usually means declaring variables at the top of their scope, often before they are used. Javascript does this automagically for us. It might be better to separate them for the sake of understanding.
The scoping rules in Javascript are not always obvious to computer professionals let alone our kids. In Javascript you can use var x = __; as an assignment statement so long as x is in the same scope it was declared. Javascript doesn’t care how many times you declare a variable in the same scope. Our kids get used to the idea that var x = __; is the assignment statement and not a declaration. Then we mix global and function scoped variables and things stop working for them.
I often see initialization of variables in the wrong place. Students will put var x = __; at the top of their programs with the assumption that it will somehow run more than once. They should be putting var x; at the top and x = __; where it actually needs to run. var becomes misunderstood as if initialization is special in some way.
When using blocks, changing from var x = __; to x = __; can result in typos as the first is usually dragged to the garbage and the second inserted after. In text mode it is trivial to make that change, but many of my kids have not switched to text yet when they need to make that change.
For these reasons, I wonder if var x = __; should be removed from the block pallet and var x; and x = __; be taught separately instead.
Hi @jdonwells,
Thanks for bringing this up. This is more nuanced than my original understanding of the concepts and I see can be important in helping make in important distinction for the concept of scope.
At the same time, var x = ___; is extremely commonly used and taught, I can see some pushback if it were to disappear from the toolbox.
I’ll forward this to the code.org team for their consideration.
Frank
I have to agree with you both. I don’t think we can get away from var x= ___ but I would like to.
I try to tell my students that var should only appear once but they still like to use it everywhere. I gave up on trying to explain score and just tell them that every time they they use they create a new variable and the old one is basically unused. That seems to be working. If they take further CS classes they can come back and tell me I wasn’t quite right! I’ll accept that.
True. It doesn’t help that Javascript scope rules have never been very good. They violate the principle of least astonishment. Increasing the restrictions for beginners is not a bad idea. Right now we are using version ES5 (2009). In version ES6 scope rules are somewhat mitigated with the addition of const and let which work as expected.
Most Javascript aficionados recommend not using var anymore, ever. Mostly due to a problem mitigated by the way App Lab handles the global context. So our problem is fortunately only with the unusual scope rules.
The change I propose is actually a band-aid over a problem recognized by the Javascript community and corrected with the release of ES6 in 2015. The real solution is of course to upgrade App Lab and stop using var.
It might be time to revisit this again after the rewrite of AP CSP.
Consider https://studio.code.org/s/csp5-2020/stage/6/puzzle/3. Here is a snippet of code:
// Create and assign variables
var heads = 0;
var tails = 0;
var totalFlips = 0;
onEvent("coin", "click", function() {
heads = 0;
tails = 0;
totalFlips = getNumber("flipNum");
for (var i = 0; i < totalFlips; i++) {
This puzzle is part of loops. After we teach them to reduce duplicate code. The example we show them here is a bad one. It works but it is very much var x = gone wrong.
We have two places where we initialize heads
, tails
, and totalFlips
. If we needed to change the initialization we could change it in the first few lines and be surprised when it doesn’t change anything.
In these types of examples I would recommend code like this:
// Create variables
var heads;
var tails;
var totalFlips;
onEvent("coin", "click", function() {
// initialize variables
heads = 0;
tails = 0;
totalFlips = getNumber("flipNum");
for (var i = 0; i < totalFlips; i++) {
It costs us nothing in an example like this to separate declaration from assignment.