4 ms·
Thanks for the reply...I definitely get the advantage and popularity of lexical scoping. I'm not sure about your claim about every language doing hoisting thou
by peeters 11y ago
Thanks for the reply...I definitely get the advantage and popularity of lexical scoping. I'm not sure about your claim about every language doing hoisting though; take Java as an example:
class Example {
String f = "foo";
void foo() {
System.out.println(f); //foo
{
System.out.println(f); //foo
String f = "bar";
System.out.println(f); //bar
}
System.out.println(f); //foo
String f = "baz";
System.out.println(f); //baz
}
}
I understand that Java doesn't perfectly match var or let, in that the lexical matching of local variables is not the same as either. But Java really doesn't seem to be doing hoisting here, and it's certainly clearer what f refers to before the local variable is declared (though I like the explicit error the TDZ gives the best).
- ajanuary 11y agoJava defines the scope of a local variable to be "the rest of the block in which the declaration appears". The variable declaration is 'hoisted' to the top of the scope, which is defined as where the variable declaration is. Tautological! The rest of your example then falls out the fact local variables can shadow member variables [1]. C# scopes local variables more similarly to javascript's "let". class Example { public void Foo() { Console.WriteLine(f); // Error: The name 'f' does not exist in the current context } public void Bar() { Console.WriteLine(f); // Error: Cannot use local variable 'f' before it is declared String f = "a"; } } In Bar, it knows about the variable f, evidenced by the fact the error message is different to Foo. In Javascript terminology, f was 'hoisted' to the top of Bar. In regular terminology, f is in the lexical scope created by Bar. [1] Local variables can only shadow member variables, not other local variables. The justification the specification gives for shadowing is so that superclasses can introduce protected member variables without forcing subclasses to rename their local variables. You can still reference the member variable using "this.memberVariable".