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