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
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals