On 03/17/2015 11:37 AM, Boris Zbarsky wrote:
> It fails because the invalid function-in-block source gets desugared by 
> SpiderMonkey like so (from your original mail) into valid JS:
> 
> if (q) {
>   var client1 = {on:function(){}};
>   client1.on('close', onclose);
>   var onclose = function onclose() {
>     console.log('dummy');
>   }
> }

Close.  To be absurdly pedantic, it's more like this:

if (q) {
  var client1 = {on:function(){}};
  client1.on('close', onclose);
  eval("var onclose;");
  onclose = function onclose() {
    console.log('dummy');
  }
}

That is, *evaluating* a function statement that's not at the top level of a 
function body, or of an entire script, *dynamically* adds a new binding to the 
function's environment, then sets it to the function object.  This is subtly 
different from the above, in that passing |onclose| to the |on| method, will 
pass the value of |onclose| visible in that scope *before* the binding is added.

So if you had:

var onclose = 42
function t()
{
  if (1) {
    var client1 = {on:function(x, y){ print(y); }};
    client1.on('close', onclose);
    function onclose() {
      console.log('dummy');
    }
  }
}
t();

it would print 42, not undefined.  (Assuming |var onclose| doesn't conflict 
with a global-property onclose on Window.prototype -- it works in our JS shell, 
at least, so the theory of it is sound.)

And yes, function statements inside blocks are just not a good idea at all.  
Don't use them!

Jeff
_______________________________________________
dev-tech-js-engine-internals mailing list
dev-tech-js-engine-internals@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals

Reply via email to