1

Why is it that when I do the following:

var a = 1;

function foo(a) {
  a = 2;
}

foo();
console.log(a); // a = 1

But I get a different result for the following:

var a = 1;

function foo() {
  a = 2;
}

foo();
console.log(a); // a = 2
j08691
  • 204,283
  • 31
  • 260
  • 272
BitByBit
  • 567
  • 4
  • 16
  • 1
    search for "js global and local scopes", you'll get it – RomanPerekhrest Dec 21 '17 at 21:30
  • 1
    Possible duplicate of [An example of variable shadowing in javascript](https://stackoverflow.com/questions/11901427/an-example-of-variable-shadowing-in-javascript) – Andreas Dec 21 '17 at 21:32
  • Or how about a third example that's based on your second example except the `a = 2` in the function is changed to `var a = 2`? – j08691 Dec 21 '17 at 21:33
  • In the first case, `a` is a parameter of the function, and thus a local variable, completely independent from the variable with the same name in the global scope. In the second case you are manipulating the variable in the global scope directly. – jcaron Dec 21 '17 at 21:33
  • To be honest I think giving it a cool name like "variable shadowing" is a bit much. It makes it seem like there's more to it, but it's just scope. – zfrisch Dec 21 '17 at 21:47
  • @RomanPerekhrest, I understand that the second example behave due to scope but what has example 1 to do with scope? – BitByBit Dec 21 '17 at 21:56

3 Answers3

1

In the first example the function foo parameter a is shadowing the global variable a and thus the value of the global variable never changes. The code in the first example is equivalent to this one:

var a = 1;

function foo(x) {
  x = 2;
}

In the second example you are referencing the global variable a inside the body of the function foo. Here no variable shadowing occurs so that you get the expected result - a is asigned the value of 2.

Tsvetan Ganev
  • 8,246
  • 4
  • 26
  • 43
0

if a is passed in as an argument to that function -- then the value of a within that function is isolated and only accessible within that function. otherwise your a defined outside the function is shared across all functions and objects.

agree with @RomanPerekhrest -- read up.

**UPDATE in reply to comment **

var a = 1; 
function foo(a) { 
  a = 2;
}
foo();
console.log(a); // a = 1

In the code above, the reference to a on lines 2 and 3 are a different variable from the a on lines 1 and 6. In the code from your comment, you are setting a to the value of x within the foo function. That's a bit different from the original question. No?

Glenn Ferrie
  • 10,290
  • 3
  • 42
  • 73
0

JavaScript doesn't really have "parameters on the left/right side." Your first example passes a parameter. Your second example uses a closure.

In programming languages, closures (also lexical closures or function closures) are techniques for implementing lexically scoped name binding in languages with first-class functions. Operationally, a closure is a record storing a function together with an environment: a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created. A closure—unlike a plain function—allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

In your first example, the variable a inside the function foo is a different variable than a outside of the function. Changing foo's parameter a has no effect on the global variable a that gets passed to console.log.

In your second example, the variable a is not a parameter, but rather a part of the environment that is captured by the function foo. The log shows a modified value of a because the assignment inside foo and the console.log call outside of foo are actually referring to the same variable.

notriddle
  • 640
  • 4
  • 10