I start to read JavaScript Patterns, some codes confused me.
var global = (function () {
return this || (1, eval)('this');
}());
Here are my questions:
Q1:
(1, eval) === eval
?
Why and how does it work?
Q2: Why not just
var global = (function () {
return this || eval('this');
}());
or
var global = (function () {
return this;
}());
The difference between (1,eval)
and plain old eval
is that the former is a value and the latter is an lvalue. It would be more obvious if it were some other identifier:
var x;
x = 1;
(1, x) = 1; // syntax error, of course!
That is (1,eval)
is an expression that yields eval
(just as say, (true && eval)
or (0 ? 0 : eval)
would), but it's not a reference to eval
.
Why do you care?
Well, the Ecma spec considers a reference to eval
to be a "direct eval call", but an expression that merely yields eval
to be an indirect one -- and indirect eval calls are guaranteed to execute in global scope.
Things I still don't know:
this
of a function at global scope not yield the global object?Some more information can be gleaned here.
EDIT
Apparently, the answer to my first question is, "almost always". A direct eval
executes from the current scope. Consider the following code:
var x = 'outer';
(function() {
var x = 'inner';
eval('console.log("direct call: " + x)');
(1,eval)('console.log("indirect call: " + x)');
})();
Not surprisingly (heh-heh), this prints out:
direct call: inner
indirect call: outer
EDIT
After more experimentation, I'm going to provisionally say that this
cannot be set to null
or undefined
. It can be set to other falsy values (0, '', NaN, false), but only very deliberately.