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
Post a Comment