Questions regarding to arrays & scope

Hello all! From my understanding of scope, arrays declared outside of a function will always be global. Thus, it is mutable within any declared function, just as the example the lesson provided.

const flowers = [‘peony’, ‘daffodil’, ‘marigold’];

function addFlower(arr) {
arr.push(‘lily’);
}

addFlower(flowers);

console.log(flowers); // Output: [‘peony’, ‘daffodil’, ‘marigold’, ‘lily’]

However, I don’t understand why this one would work. isn’t ‘‘concept.push(‘ABC’)’’ not supposed to access the ‘‘Concept’’ variable?

function TestingArray(){
const concept = [‘arrays’, ‘can’, ‘be’, ‘mutated’];
if(concept.length > 2){
concept.push(‘ABC’)
console.log(concept)
}else{
console.log(‘DEF’)
console.log(concept)
}
}
TestingArray() //Output:[ ‘arrays’, ‘can’, ‘be’, ‘mutated’, ‘ABC’ ]

Hey there and welcome to the forums!

In this situation, concept is a local variable for the function TestingArray(), so it’s perfectly expected that it can be accessed within this function as demonstrated in the code you sent. The situation where it shouldn’t work would be if concept was within the testing function but the if statement was outside of the function, like below:

function TestingArray(){ const concept = ['arrays', 'can', 'be', 'mutated']; } if(concept.length > 2){ concept.push('ABC') console.log(concept) }else{ console.log('DEF') console.log(concept) } TestingArray() //Output:[ 'arrays', 'can', 'be', 'mutated', 'ABC' ]

Note how in the above code an error is thrown, as concept is defined within the function, but the if statement isn’t in the function.

Hopefully that clears it up!

Thanks for your help Adam! However, I’m still a little bit confused with the situation that I mentioned above. Aren’t the local variables can only be accessed by the line lines of code within that block? If that’s the case, wasn’t the variable ‘concept’ and ‘concept.push(‘ABC’)’ located in two SEPARATE blocks and they shouldn’t be able to access each other?

Local scope really only applies to things like files, classes and functions. In the case of your example, all of the code was within a single function, therefore everything in that function can be accessed elsewhere also within that function, as it was. In terms of scope, if statement blocks don’t have their own scope, and so that can be considered part of the same scope as the function as a whole.

I think that’s true for Python but not for JavaScript. (If-blocks seem to have a scope in JavaScript.)

function doStuff() { let x = 3; if (x == 3) { let y = 2; } console.log(y); // fails outside the if-block } doStuff();

Ah so interesting thing here (and something I’ve just learned too, despite working with JS for years now and never encountering an issue with this). I am correct in saying that JS doesn’t come with native block scoping, however it’s specifically the ES6 let and const variable declarations that add block scope. So you’ll notice if you change let y = 2; to var y = 2;, the code now works. This is something that was specifically added as part and parcel with let and const which is interesting.

I suspect the reason I’ve never had this issue is that I very rarely declare variables (if ever) inside of an if statement. The variable is declared beforehand in the function scope, and then assigned to within the if statement, like so:

function test() {
  let y;
  if (true) {
    y = 5;
  } else {
    y = 10;
  }
}

This is just personally how I tend to do things so that would explain why I never encountered this before. Good to always learn something new I took for granted!

2 Likes

Does that mean the rules of scope is different in array?

Sorry to bother you ,Jan. However, does that mean the rules of scope is different in array?

The rules are the same for an array and also for array methods.

If that’s the case, then I’m confused with the example that I mentioned above. How could ‘concept.push(‘ABC’)’ access to the variable ‘concept’? aren’t those two are located in two SEPERATE code blocks? (One is located located in the if-statement code block and the other one located in the function’s code block)

The if statement is encapsulated within the function code block, so there’s a hierarchy there. The structure we have at it’s bare bones is:

javascript file
|
|
|___function definition
    |
    |
    |___concept array declaration
    |
    |
    |___ifelse statement
|___|
|
|
|___function call

Hopefully this structure makes a decent amount of sense. We have the javascript file furthest to the left, which everything is contained within. Anything declared at this level would be considered a global variable and would be accessible throughout the javascript file. Then at the next level we have your function definition and your function call at the same level.

Then if we go deeper again, we have the ifelse statement and the array declaration at the same level within the function definition. The important distinction here is that the concept array is declared using the const keyword inside the function but outside the if statement. Therefore the concept array is available to anything else fully contained within the function declaration, which the if statement is.

So if you declared a variable, say let test = 2 within the if statement, that would only be available to other parts within the if statement block, as demonstrated in @janbazant1107978602’s example. And it’s important to point out that this is only the case when using let and const to declare variables. If you use the more traditional var then the if statement block is ignored and doesn’t get it’s own scope.

I appreciate this was a long and complex explanation so let me know if it still doesn’t make sense.

2 Likes

I guess I know what makes the difference now. Thanks for the detailed explanation, Adam!
@janbazant1107978602 credit to Jan as well! Thanks Jan!