FAQ: Scope - Practice Good Scoping

This community-built FAQ covers the “Practice Good Scoping” exercise from the lesson “Scope”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

Introduction To JavaScript

FAQs on the exercise Practice Good Scoping

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

A little off the scoping topic but not totally. I used a standard if statement on this lesson and got the desired results. However I was trying to give myself some practice with the ternary operator and cannot duplicate the same result. I’ve tried the following ways.
lightWaves = region === ‘The Arctic’ ? (‘Northern Lights’, console.log(lightWaves)) : (‘Moon’, console.log(lightWaves));
this gives me Moonlight, undefined as a result
I’ve also tried
region === ‘The Arctic’ ? (‘Northern Lights’, console.log(lightWaves)) : (‘Moon’, console.log(lightWaves));
With a result of Moonlight, Moonlight.
both these are still being ran inside the function.
What would the correct ternary operator expression be to achieve this same out come?

2 Likes

We should not log the variable we are assigning to from inside the ternary. Let the value be assigned, then log the outcome.

lightWaves = region === 'The Arctic' ? 'Northern Lights' : 'Moon';
console.log(lightWaves);
3 Likes

So, with block scope, in the example of ‘Practice Good Scoping’ would there ever be a situation where:

let color = ‘blue’

would be considered global to the function? I see that within the if statement that color is redefined as pink. or was that a condition of creating a new variable called color within that block via the:

let color = ‘pink’

meaning, if they just said:

color = ‘pink’

would that have updated the original color = ‘blue’ to be color = ‘pink’ ?

thus, in my mind, i would think that is a global variable within that function only. thank you

3 Likes

Yes, when it is written in global namespace as a property of the window object. That would be its containing block, and top of scope for the whole shebang. We call that the top of the scope chain.

The scope it belongs to will be determined by the block it is in.

 > function foo() {
       let bar = 42
       for (let bar of [1,2,3,4,5]) {
           console.log(bar);
       }
       console.log(bar)
   }
<- undefined
 > let bar = 0;
 > foo()
   1
   2
   3
   4
   5
   42
<- undefined
 > console.log(bar)
   0
<- undefined
1 Like

I don’t understand why the declarations of lightWaves are causing a syntax error. If I switch the let and var keywords in the lines that declare lightWaves with each other, the error disappears. The program then prints:
Northern Lights
Moonlight

I really don’t understand why the problem asks me to define a new variable lightWaves with the keyword let, since lightWaves was already declared earlier before the if statement. How come this doesn’t produce an error but the code below does, when I declare a lightWaves with let in the function and then another lightWaves with var?

const logVisibleLightWaves = () =>
{
let lightWaves = ‘Moonlight’;
var region = ‘The Arctic’;

if (region === ‘The Arctic’)
{
var lightWaves = ‘Northern Lights’;
console.log(lightWaves);
}
console.log(lightWaves);
};
logVisibleLightWaves();

I’m not sure if I am missing some instructions but exercise 6/7 instructs as so:

1.
Inside the function body of logVisibleLightWaves() , beneath the region variable and before the provided console.log() statement, create an if statement that checks if the region is the 'The Arctic' . "

The problem is that I am not sure what ‘region’ should equal. I assumed region but I am having trouble following the instructions enough to get to step 2.
Please help
I have provided the code that I input:

function logVisibleLightWaves() {
let lightWaves =‘Moonlight’;
let region = ‘The Arctic’;
if (region === ‘The Arctic’){}}

That is correct, so far. Now just fill in the action that should take place inside the if block.

This may be a segue, or it may be what the author wants us to see, but either way…

if (region === 'The Arctic') {
    let lightWaves = "Northern Lights";
}

If we log or return lightWaves, what will it be?

1. Moonlight
2. Northern Lights

Give it a guess…

It would be ‘Nothern Lights’. I see it now. The problem was that the code did not auto populate for me under main.js but now it has. I changed browsers from edge to chrome, not sure if that was the fix.

Thank you for you help

Are you sure? Remember, let has block scope so the variable is inaccessible outside of the block. Mine was a trick question, but with express meaning.

const logVisibleLightWaves = () => {
  let lightWaves = 'Moonlight';
  let region = 'The Arctic';
  // Add if statement here:
  if (region === 'The Arctic') {
    let lightWaves = "Northern Lights";
  }
  console.log(lightWaves);
};

logVisibleLightWaves();
Moonlight

If we want to return “Northern LIghts” then we would remove let from inside the if statement.

1 Like

Wouldn’t it be bad form to have a global variable and local variable with the same name? I can see reusing local variable names, like ‘num’ or ‘index’. But having 2 separate variables with the same name seems like a bad idea to me.

Local variables declared with let or const (or var) will shadow a global variable of the same name.

While we use block scope, we still pollute our namespace by reusing the same variable name twice. A better practice would be to rename the variable inside the block.

Referring to the text above, should we be revising the following code:

const logSkyColor = () => {
  const dusk = true;
  let color = 'blue'; 
  if (dusk) {
    let color = 'pink';
    console.log(color); // pink
  }
  console.log(color); // blue 
};

to this instead:

const logSkyColor = () => {
  const dusk = true;
  let color = 'blue'; 
  if (dusk) {
    let color = duskColor;
    let duskColor = 'pink';
    console.log(color); // pink
  }
  console.log(color); // blue 
};

Thank you!

This should raise an undefined variable error as the duskColor variable is assigned before it is defined.

So… global variables are mutable within the local scope, but locally defined variables within a function are not mutable within sub-scopes of that function? LOL. Typical nonsensible garbage from Garbagescript.

If i’m understanding you correctly that’s not entirely true.

the reason lightwaves is printing 2 separate values is because we are defining it twice. once in the function block and a second time in the “sub-scope” block (the ‘if’ block).
if you remove whatever identifier you used for lightwaves in the ‘if’ block (const, let, var) it will change lightwaves value in the function block. you will see northern lights printed twice.

thus, locally defined variables within a function ARE in fact mutable within “sub-scopes”.

1 Like

I did not understand why the second console.log(lightWaves); after the closure of the “if” was not printing anything. Could someone please let me know. It should actually print “Moonlight” if I am not wrong.

Yes, it should. See the post above from 22 Feb. If your code looks like that, then Moonlight should be logged.

I agree with you, this chapter is not well explained, IMHO (I am new to JS, not to coding/programming). Using “let” you are not assigning a new value to the global variable “color”, you are CREATING a new, local to the “if” block, “color” variable with higher priority inside its block (in fact its “new” value is shown inside the “if” block) instead, leaving untouched the global “color” variable. This is my understanding, I am ready to be corrected by Moderators, with better JS knowledge.

1 Like

Hello, in the introduction to this part they say: " While we use block scope, we still pollute our namespace by reusing the same variable name twice. A better practice would be to rename the variable inside the block." But then in the example they are ignoring their satement and define the variable

let lightWaves

twice.
So would it be better to rename this according to the quoted sentence?

6 Likes