-
-
Save jrburke/1152608 to your computer and use it in GitHub Desktop.
//Came across this in the es-discuss list, on the "clean scope" thread: | |
https://mail.mozilla.org/pipermail/es-discuss/2011-August/thread.html#16294 | |
//I do not understand what the "null," part buys. | |
//Has to do something with scope(?), but at least in Firebug, | |
//I can see foo inside the string being evaled. | |
var foo = 'foo'; | |
(null,eval)('(function(){console.log(foo);}())'); | |
//Prints "foo" in Firebug console. |
(null,eval)
makes an indirect eval call, which executes the code in the global scope (rather than the scope of the caller).
@kangax has an excellent article about global/indirect eval here:
http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_theory
Try this:
(null, console.log)('blah');
It seems to do the same thing as these:
(console.warn, console.log)('blah');
(console.log)('blah');
console.log('blah');
So I guess it has nothing to do with eval, maybe the goal was to go around a particular browser quirk?
Ah, I should have waited a bit for someone to post the correct answer :p
Also, if you define foo in the global scope and then use an indirect eval foo will still be in scope. That's another reason why you want to wrap those 2 statements in a function.
Thanks all for the answers.
It's absolutely about eval, not about browser quirks. When you write
eval(/* blah */)
or even
(((((eval)))))(/* blah */)
it's specified in the standard to be a "direct eval" which has access to the local scope. But when you write
(null, eval)(/* blah */)
it's an "indirect eval," which is evaluated in the global scope.
The null isn't particularly special; it would also work to replace the null with 42 or /someregex/ or "this is a srsly weird language feature".
Dave
+1 for @kangax's definitive source on global eval.
http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_theory
ah... i learn something new everyday ... :)
so its about whether the reference is named or not
eval() would execute in local scope, but any other reference to eval would execute in global scope
the following execute in a global scope
- (null, eval)('')
- (x=eval)('')
- var x=eval; x('')
- var eval=window.eval; eval('')
- window.eval('')
- eval.call(window,'')
edit: and i found this http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_examples :)
Try it wrapped in a function, Firebug uses eval itself.
vs
null
itself is not relevant, the important thing is that the comma expression results in theeval
function but not by a directly named reference.