0

i have seen this below link and answer but i am confused....

javsacript variable scopes

var color = "black";
var r = function (x, y) {
    if(y == 1){
        var color = "red"; //refers to local color, here color points to red color in memory
    } else {
        console.log('inside else block');
        color = "red color";//refers to global color, here color points to red color in memory
    }
    //var color = "red color"; //refers to local color, here color points to red color in memory
    //color = "red";//refers to global color, here color points to red color in memory
    if (x > 2 ){
        return x*2;
    } else {

        return x * x;
    }
}
r(5, 2);
console.log(color);

but the output is black instead of red color which i expected....since inside the else block it is referring to the global variable right?

without the if block in there i get red , as expected (see below code).... if it is only function scope then how does the value change in the above scenario?

var color = "black";
var r = function (x, y) {

    //var color = "red color"; //refers to local color, here color points to red color in memory
    color = "red";//refers to global color, here color points to red color in memory
    if (x > 2 ){
        return x*2;
    } else {

        return x * x;
    }
}
r(5, 2);
console.log(color);

From msdn,

JavaScript does not support block scope (in which a set of braces {. . .} defines a new scope), except in the special case of block-scoped variables

Community
  • 1
  • 1
coolstoner
  • 719
  • 2
  • 9
  • 20

3 Answers3

2

but the output is black instead of red color which i expected....since inside the else block it is referring to the global variable right?

No. var declares a variable in the scope of the current function, not the block, and it is hoisted so it doesn't matter where in the function you put it.

You can't conditionally apply var.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
2

As you declared color = "red" with 'var' keyword, this will create a new variable 'color' only in that scope (function r) which will override the variable color only in that scope (function r).

When you call console.log (in global or window scope) you refer to the variable color declared by var keyword in that scope.

"...since inside the else block it is referring to the global variable right?"

No, all the variables are initialized (hoisted) on the function start. So here also you are referring to the same variable color.

Simple rule use 'var' to define a new variable (overriding the outer scope) in a scope, and assume all your 'var' statements declaration (not assignment) are moved to the start of a function (scope).

i.e. your code is equivalent to :

 window.color = "black"; // assuming this is inside <script> tag directly
var r = function (x, y) {
    var color; // it is your local 'color'
    if(y == 1){
        color = "red"; //refers to local color, here color points to red color in memory "YES"
    } else {
        console.log('inside else block');
        color = "red color";//NOT refers to global color, here color points to red color in memory
    }

    if (x > 2 ){
        return x*2;
    } else {

        return x * x;
    }
}
r(5, 2);
console.log(window.color); // the window scope.

You are assuming it the java way — {} encloses a scope. For javascript: function(){} encloses a scope. not "if" and every scope has access to the variables in outer scope.

kloik friend
  • 119
  • 5
  • this is more well explained though...i missed this keyline....`No, all the variables are initialized (hoisted) on the function start.` – coolstoner Oct 08 '16 at 11:08
  • Before executing your function block all the 'var' statements are moved the beginning of the code, like this — var color; // it is your local 'color' This is what they call 'hoisting' variables. In fact if you dont use 'var' the js engine will assume the declaration line. It is a good practice to initialize all your variables you will be using on the first line of the function. – kloik friend Oct 08 '16 at 11:11
1

but the output is black instead of red color

That is because inside the block (which is inside a function) color was assigned a new reference with value red color which got garbage collected as soon as scope of the enclosing function ended.

Javascript variables are function-scoped, and a new reference assigned inside a function is relevant only till the scope of function lasts.

outside the function, older reference and its value black was retained.

Update

As per your comment,

it goes inside the else block and then i do no use var but just color so it should refer to global color right?

No, variable gets hoisted before the function starts getting executed so it doesn't matter if the if condition is executed or not.

gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • i have edited my question...if i use `var` the variable is local to the function but else it is global... but if an `if` block is used the above condition is thrown out of the window.... `var` or `no var` i get the global value only....confused! – coolstoner Oct 08 '16 at 10:50
  • This is it. Is easy to see how this works by replacing 'var color´ with window.color and 'color = "red color"' with 'window.color = "red color"'. Then the function works as OP expected. – Sergeon Oct 08 '16 at 10:50
  • @coolstoner in the second example, you should be getting `red` right? – gurvinder372 Oct 08 '16 at 10:54
  • @gurvinder: yes and thats kind of driving me crazy....i expect it to behave the same `with/without` an `if-else` clause...but it isnt...and they say it is function scoped not block scoped.... – coolstoner Oct 08 '16 at 10:57
  • @coolstoner you are using var in the first example, and second example is without `var`. It has little to do with `if else`. – gurvinder372 Oct 08 '16 at 10:59
  • @gurvinder372 if thats the case then in the first code construct shouldnt OP be `red color` instead of `black`....it goes inside the `else` block and then i do no use `var` but just `color` so it should refer to `global` color right? but i get the OP as `black` – coolstoner Oct 08 '16 at 11:01
  • 1
    @coolstoner **No**, but now I get your confusion. Variable gets hoisted before the execution of method starts, so it doesn't matter if the `if` condition gets executed or not. – gurvinder372 Oct 08 '16 at 11:06