-1
<html>
<head>
<script type='text/javascript'>
    var process = function (test) {
      var i = test;
      this.echo = function () { console.log(i); };
    };
    var test = 'hai';
    var hai = new process(test);
    hai.echo();
    test = 'sorry';
    hai.echo();
</script>
</head>
<body style='height:1000px;width:100%'>
</body>    

On executing the above test script I'm getting 'sorry' twice which I expected to be 'hai' then 'hai'.

When I change line 5 as [gave a random try]

var i = (function () {return test;})();

I got it 'hai' & 'hai'

How does it work in the case 2 & why didn't it in case 1?

AFAI, javascript does variable hoisting and because of that test will be initialized to undefined in the beginning of scope and will be reassigned as and when it is assigned with the values. But here that didn't help me out.

Tamil
  • 5,260
  • 9
  • 40
  • 61

3 Answers3

3

You're confusing pass by reference with pass by value. JavaScript only allows the latter (despite what you may read elswhere).

In this case, you're passing the value "hai" to the process constructor. That value is then stored, in the inner scope, to the i variable. Changing the value of test after that will not change the value of i.

Neither of your test cases work how you expected, for the same reason.

Community
  • 1
  • 1
Andy E
  • 338,112
  • 86
  • 474
  • 445
2

Your quoted code does not behave as you've described. But trying to answer the question anyway, here's your code with some inline explanation:

var process = function (test) {
  var i = test;

  // Here you're creating a "closure" over the context of
  // this specific call to this function. So the `i` local
  // variable lives on, even after this function call
  // terminates.
  this.echo = function () { console.log(i); };
};

// This `test` variable is *completely and totally* unrelated to the
// `test` argument to your function above. They do not interact in
// any way.
var test = 'hai';

// Here, yu're passing the *value* of the `test` variable ("hai")
// into the function. The function has no reference to the `test`
// variable at all (er, not a relevant way; details below). From
// the function's point of view, it's *exactly* like
// `var hai = new process("hai");`
var hai = new process(test);

// This will show "hai"
hai.echo();

// This will also show "hai", because again, the `i` in the `echo`
// function is the local variable in the call to `new process` above;
// it is in no way whatsoever related to the `test` variable here.
test = 'sorry';
hai.echo();

More to explore (in my blog): Closures are not complicated


Details on my note about how the process function doesn't have a relevant reference to the test variable: Technically, the function you're assigning to process does have a reference to the test variable because it's a closure over the scope in which the test variable is defined. But it's not using that, because it has its own test argument and that symbol shadows (overrides) the one from the containing scope. None of which has anything to do with your passing test into the call to the process function, which is why it's irrelevant.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

It will display 2 time hai. It is not possible to show sorry twice with this script as stored variable i in locale scope of function echo and i is set only once to hai

user160820
  • 14,866
  • 22
  • 67
  • 94