function foo0() {
var bar = 2;
alert("outer block: "+bar);
if (true) {
var bar = 3;
alert("inner block: "+bar);
}
alert("outer block: "+bar);
}
Because JavaScript scoping is at the function and object levels, block scoping can be simulated with anonymous functions and anonymous objects.
Function-based Block Scoping
Anonymous functions can simulate block scoping by defining a closure and calling it:
function foo1a() {
var bar = 2;
alert("outer block: "+bar);
if (true) (function() {
var bar = 3;
alert("inner block: "+bar);
})();
alert("outer block: "+bar);
}
The parentheses around the closure are necessary to avoid a syntax error when calling the closure immediately. Formal arguments are also considered to be at the function scope, and they can be used to bind the block scoped variables:
function foo1b() {
var bar = 2;
alert("outer block: "+bar);
if (true) (function(bar) {
alert("inner block: "+bar);
})(3);
alert("outer block: "+bar);
}
Another implementation of block scoping with closures uses the new operator that automatically calls its function:
function foo1c() {
var bar = 2;
alert("outer block: "+bar);
if (true) new function() {
var bar = 3;
alert("inner block: "+bar);
};
alert("outer block: "+bar);
}
The syntax of the new operator is a bit tidier.
Object-Based Block Scoping
Just as an anonymous function can implement block scoping, so too can an anonymous object, using the with statement:
function foo2a() {
var bar = 2;
alert("outer block: "+bar);
if (true) with({ bar:3 }) {
alert("inner block: "+bar);
}
alert("outer block: "+bar);
}
Of all of these examples, the with statement has the tidiest syntax -- but only those members in the anonymous object are block scoped. Thus, variables of both function and block scope can be mixed within the same block:
function foo2b() {
var bar = 2;
var baz = 1;
alert("outer block: "+baz);
if (true) with({ bar:3 }) {
var baz = 4;
alert("inner block: "+baz);
}
alert("outer block: "+baz);
}
In this example, the second outer block alert for baz is 4, because baz still has function scope. It remains to be seen whether this ability to mix scoping is a bug (more confusing) or a feature (more flexible) for the with statement version.
No comments:
Post a Comment