Friday afternoon scoping quiz

P T Withington ptw at pobox.com
Fri Feb 5 14:42:54 PST 2010


On 2010-02-05, at 17:25, Brendan Eich wrote:

> On Feb 5, 2010, at 2:14 PM, P T Withington wrote:
> 
>> ({
>> 'foo': 20,
>> 'test': function () {
>>   var f = function () {
>>     alert("foo:"+ foo);
>>     alert("this.foo:"+ this.foo);
>>     alert("bar:"+ bar);
>>   }
>>   with (this) {
>>     var foo = 42;
>>     var bar = 21;
>>     f.call(this);
>>   }
> 
> "Doctor, it hurts when I use 'with' in JavaScript!"

Indeed!

>> }
>> }).test();
>> 
>> --
>> 
>> By my reading, `foo` and `bar` are declared and initialized in `test`, and closed over by `f`.  I expect to see:
>> 
>> foo:42
>> this.foo:20
>> bar:21
>> 
>> But in Rhino, Firefox, Safari and Opera I am seeing:
>> 
>> foo:undefined
>> this.foo:42
>> bar:21
> 
> This is correct. The vars are hoisted but the initialization of foo puts 42 where it found foo on the scope chain, in this.foo. There's no 'bar' property in |this| so that goes in the var.

Interesting!  I couldn't convince myself that var hoisting would be quite so literal.

>> Flash 10 gives me the answer I expected.  I have not tested other JS engines.
> 
> Flash 10 bug.

I will report.  Thanks.


More information about the es-discuss mailing list