0

How are the variables scoped, initialized and used outside and inside javascript functions? I have written following code:

<div id="output">
</div>

<script>
var calculator = function()
{
        var x = 5;
        getx = function(){
           return x;
        }
        return { x:x, getx };
}();
document.getElementById("output").innerHTML = calculator.x;
calculator.x=10;
document.getElementById("output").innerHTML += " "+ calculator.x + " "+calculator.getx();
</script>

I read that in JS execution, code is first scanned for all the variables declaration and then functions are executed.

var x defined inside calculator object is value type as its integer.

getx being nested function and as per closure will have access to variable "x" even after return of getx is executed.

First output for calculator.x is as expected=5;

Second output for calculator.x is as expected=10; (as x is modified)

Third output for calculator.getx() is =5; (I am not able to understand this)

"x" being value type, it should have modified value inside function scope too and third output should be=10. What am I missing here?

Sahil Sharma
  • 3,847
  • 6
  • 48
  • 98

1 Answers1

1
calculator.x = 10 

adds x to the property of the function
calculator now refers to the object { x:x, getx } and the value you are changing is not the variable x but the property x of calculator
to access the change in property you will need to output this.x

<div id="output">
</div>

<script>
var calculator = function()
{
        var x = 5;
        getx = function(){
           return this.x;
        }
        return { x:x, getx };
}();
document.getElementById("output").innerHTML = calculator.x;
calculator.x=10;
document.getElementById("output").innerHTML += " "+ calculator.x + " "+calculator.getx();
</script>

To prove it look at the below code, clearly the variable x was not being changed, instead the property was being change which getx could not access

<div id="output">
</div>

<script>
var calculator = function()
{
        var x = 5;
        getx = function(){
           return x;
        }
        setx = function(a){
          x = a;
        }
        return { x:x, getx, setx };
}();
document.getElementById("output").innerHTML = calculator.x;
calculator.setx(10);
document.getElementById("output").innerHTML += " "+ calculator.x + " "+calculator.getx();
</script>
marvel308
  • 10,288
  • 1
  • 21
  • 32
  • probably this is something I am looking for, but didn't get how return x differs from return this.x? – Sahil Sharma Aug 13 '17 at 19:13
  • x was being added to the property of calculator, but the x which getx() was accessing was the variable defined inside, you were changing the property but the variable remained unchanged – marvel308 Aug 13 '17 at 19:15
  • I get the 2nd example where you are using set, but still not got the reason how its working in 1st example with this keyword.. how does this.x enables it to return back added property (i.e. x) value?? – Sahil Sharma Aug 13 '17 at 19:22
  • check http://ideone.com/q7DR5E, this shows the x that you were referring was actually the property of the object calculator and not the variable inside – marvel308 Aug 13 '17 at 19:28
  • now if you want getx() to use this change in property then it would have to reference it using the this keyword – marvel308 Aug 13 '17 at 19:30
  • then how come in my 1st output, I am getting back 5? does calculator.x = 10 creates new property inside calculator object? If yes, what happens to already existing propery var x =5; declared inside calculator? – Sahil Sharma Aug 13 '17 at 19:35
  • 1
    return { x:x, getx } makes a property x for calculator since you are now referring to the object that is { x:x, getx }, the variable inside remains unchanged hence when you access it, it returns 5 but when you specifically set it to 10 using setx() in the 2nd example, then it changes – marvel308 Aug 13 '17 at 19:38
  • return { x:x, getx } all these would be reference type properties, correct?] – Sahil Sharma Aug 13 '17 at 19:41
  • changing the value of property x would not alter the variable x – marvel308 Aug 13 '17 at 19:42
  • return { x:x, getx } , once we execute this, the value 5 is copies to variable x and after that, it has its own memory, correct? – Sahil Sharma Aug 13 '17 at 19:44
  • yes, also refer to the discussion in https://stackoverflow.com/questions/7744611/pass-variables-by-reference-in-javascript to further clear your doubt – marvel308 Aug 13 '17 at 19:45