If the "with" statement in Javascript creates a new scope, why does this closure doesn't contain the new "x" in new scope each time? -


if with statement in javascript creates new scope, shouldn't clicking on links show different x in different scopes? doesn't.

<a href="#" id="link1">ha link 1</a> <a href="#" id="link2">ha link 2</a> <a href="#" id="link3">ha link 3</a> <a href="#" id="link4">ha link 4</a> <a href="#" id="link5">ha link 5</a>   <script type="text/javascript">      (i = 1; <= 5; i++) {          with({foo:"bar"}) {             var x = i;             document.getelementbyid('link' + i).onclick = function() { alert(x); return false; }         }      }  </script> 

the with statement doesn't creates full new lexical scope, introduces object in front of scope chain, example, if capture i variable, work:

for (var = 1; <= 5; i++) {   with({x:i}) {     document.getelementbyid('link' + i).onclick = function() {       alert(x);       return false;     };   } } 

let me try explain better example:

var x = 10, y = 10;   // step 1  ({x: 20}) {      // step 2    var x = 30, y = 30; // step 3    alert(x); // 30   alert(y); // 30 }  alert(x); // 10 alert(y); // 30 

in step 1, x , y variables declared , part of first object in scope chain, global object.

in step 2, new object ({x:20}) introduced scope chain with statement, scope chain looks this:

    ________              ________   | x = 10 | <--------- | x = 20 |   | y = 10 |             ¯¯¯¯¯¯¯¯¯    ¯¯¯¯¯¯¯¯  

in step 3, var statement executed, has no effect because said before, functions create full lexical scope.

the var statement has no effect, assignment has, when x variable resolved, reached on first object on scope chain, 1 introduced using with.

the y identifier resolved also, not found on first object in chain, lookup continues up, , finds on last object, scope chain after assignments looks this:

    ________              ________   | x = 10 | <--------- | x = 30 |   | y = 30 |             ¯¯¯¯¯¯¯¯¯    ¯¯¯¯¯¯¯¯  

when with statement ends, scope chain restored:

    ________    | x = 10 |   | y = 30 |    ¯¯¯¯¯¯¯¯  

edit: let me expand little bit , talk functions.

when function created current parent scope bound, example:

var fn; // augment scope chain ({foo: "bar"}) {   fn = function () { // create function     return foo;   }; }​​ // restored scope chain fn(); // "bar", foo still accessible inside fn 

a new lexical scope created , added scope chain when function executed.

basically identifiers (names) of function arguments, variables declared var , functions declared function statement, bound properties of new object created behind scenes, before function executes (when controls enters new execution context).

this object not accessible through code, called variable object, example:

var x = 10, y = 10;   // step 1  (function () {        // step 2   var x, y;     x = 30;             // step 4   y = 30;     alert(x); // 30   alert(y); // 30 })();                 // step 3  alert(x); // 10       // step 5 alert(y); // 10 

in step 1, again in first example, x , y variables declared , part of first object in scope chain, global object.

in step 2, new function object created, parent scope stored in moment, [[scope]] of function, containing x , y.

in step 3, function invoked, starting variable instantiation process, creates new object in scope chain, containing locally scoped x , y variables declared inside new function, scope chain @ moment looks this:

   parent scope           variable object    ________              _______________   | x = 10 | <--------- | x = undefined |   | y = 10 |            | y = undefined |     ¯¯¯¯¯¯¯¯              ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯  

then in step 4, assignment of x , y done, since new lexical scope has been created, doesn't affect outer values.

   parent scope           variable object    ________              ________   | x = 10 | <--------- | x = 30 |   | y = 10 |            | y = 30 |     ¯¯¯¯¯¯¯¯              ¯¯¯¯¯¯¯¯  

and finally, in step 5, function ends , scope chain restored original state.

    ________    | x = 10 |   | y = 10 |    ¯¯¯¯¯¯¯¯  

recommended lectures:


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -