17

I am new to JS and having a doubt with the below example. Please see the inline comments.

function outer() {
 var x = 5;
 console.log("outer",x); // Prints 5
 console.log("-----------");
 function inner() {
  var x = 6;
  console.log("inner",x); // Prints 6
  console.log("outer",x); // Prints 6. How to print 5
  console.log("-----------");
  function _inner() {
   var x = 7;
   console.log("_inner",x); // Prints 7
   console.log("inner",x); // Prints 7. How to print 6
   console.log("outer",x); // Prints 7. How to print 5
   console.log("-----------");
  }
  _inner();
 }
 inner();
}
outer();
halfer
  • 19,824
  • 17
  • 99
  • 186
Roy
  • 503
  • 2
  • 8
  • 20
  • 2
    pass as parameters to inner functions with a different name I suppose? – Tahir Ahmed Aug 16 '15 at 14:55
  • 1
    If a local variable is declared with a name that's the same as a more-global variable, then (excepting the case of the actual global scope) there is just no way to access the outer variable. – Pointy Aug 16 '15 at 14:57
  • Is it intentional that all three variables have exactly the same name? By simply changing the names of "inner" variable to `y` and the "_inner" variable to `z` you will get your expected results. – Lix Aug 16 '15 at 14:57
  • @Lix... I intentionally kept it as 'x' ... I know if I have different variable names or pass as an argument ...the example will work perfectly fine... just wanted to know is there any way like the example. – Roy Aug 16 '15 at 15:05
  • @Roy - the question then is why do you need to have the same variable names? – Lix Aug 16 '15 at 15:06
  • 1
    @Roy: There's no mechanism to do exactly what you want. The solution is to use variables with different names. What you want is completely impossible in javascript (at least up to ES6) – slebetman Aug 16 '15 at 15:10
  • already answered here.. http://stackoverflow.com/questions/4001414/javascript-access-local-variable-with-same-name-in-inner-and-outer-scope – Pavan Andhukuri Aug 16 '15 at 15:11

3 Answers3

8

May be this helps you. Assign your variables to your nested functions because therefore it is clear what varible should be used but they have to differ from each other in some way(name or via namespace):

function outer() {
    var x = 5;
    // or via namespace
    // var out = { x : 5 };
    console.log("outer",x); // 5
    console.log("-----------");
    function inner() {
        inner.x = 6;
        console.log("inner",inner.x); // 6
        console.log("outer",x); // 5
        console.log("-----------");
        function _inner() {
            _inner.x = 7;
            console.log("_inner",_inner.x); // 7
            console.log("inner",inner.x); // 6
            console.log("outer",x); // 5
            // namespace 
            // console.log("outer",out.x); // 5
            console.log("-----------");
        }
        _inner();
    }
    inner();
}
outer();

In this example only two of three varibles are assign(not outer x) to functions because otherwise you could assess outer.x from outside outer function and assign it any value:

function outer(){
   outer.x = 5;
   ...
}
// assign any value outside outer function
outer.x = 34;

But when a local variable is defined:

function outer(){
   var x = 23;
}

Then there is no chance to assign this local variable(x) any value from outside outer function.

Blauharley
  • 4,186
  • 6
  • 28
  • 47
  • is `outer.x = 5;` means creating prototype property ? – Roy Aug 16 '15 at 15:12
  • 2
    no. you have to use prototype like: outer.prototype.x in this fashion all derived objects of type outer have access to this variable so it's a kind of class variable. Writing outer.x is also possible and all object have access to it as well but it's not recommended since inheritage works only on prototype properly and you do not have to write the function name(outer) again when accessing x variable somewhere within a object method. Hope that i wrote not that complicated :) – Blauharley Aug 17 '15 at 08:28
3

Javascript doesn't by default have blocked scope variable like many programming languages. This means that the variable x like you declared above, is the same variable.

Variable declarations, wherever they occur, are processed before any code is executed. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

I would suggest to not use the same variable name in a nested function. It becomes hard to read and debug. Also do you really need to have nested function ?

function outer() {
    var x = 5;
    console.log("outer",x); // Prints 5
    console.log("-----------");
    inner(x);
}
function inner(x1) {
    var x = 6;
    console.log("inner",x); // Prints 6
    console.log("outer",x1); // Prints 5
    console.log("-----------");
    _inner(x,x1);
}
function _inner(x1, x2) {
    var x = 7;
    console.log("_inner",x); // Prints 7
    console.log("inner",x1); // Prints 6. 
    console.log("outer",x2); // Prints 5.
    console.log("-----------");
}
outer();

Or you could use object declaring it like so

function outer() {
    var x = {
      outer: 5
    };
    console.log("outer",x,outer); // Prints 5
    console.log("-----------");
    function inner() {
        x.inner = 6;
        console.log("inner",x.outer); // Prints 6
        console.log("outer",x.inner); // Prints 6. How to print 5
        console.log("-----------");
        function _inner() {
            x._inner = 7;
            console.log("_inner",x._inner); // Prints 7
            console.log("inner",x.inner); // Prints 7. How to print 6
            console.log("outer",x.outer); // Prints 7. How to print 5
            console.log("-----------");
        }
        _inner();
    }
    inner();
}
outer();
Axel Mani
  • 159
  • 2
  • 12
0

when we reuse the variable name inside an method then only block-scope will work. means scope will be work. Means for these variables, the braces {. . .} will define the scope.

what you can try is define Global Variables

var x = 5;
    var innerx = 5;
    var _innerx = 5;
    function outer() {
    }
   
ManishSingh
  • 1,016
  • 11
  • 9
  • **use different names for variables** function outer() { var x = 5; function inner() { var innerx = 6; function _inner() { var _innerx = 7; } } } – ManishSingh Aug 16 '15 at 15:26