Some forms of indirect eval
fail in Opera, and, I'm told, in Safari.
[eval][0]('')
Unhandled Error: eval called with invalid this object
Notice that it fails when evaluating an empty string... as far as I can tell it should return undefined
.
Other forms, like (0,eval)('')
, seem to work fine.
Running the examples from this test suite by kangax, I see several forms that fail with the "invalid this object" message in Opera, but not Chrome or Firefox.
Can anyone explain why this happens? What dictates this behavior? It seems intentional, does it adhere to some part of the standard I don't know about?
Related -- SO discussion about indirect vs. direct eval.
Also -- Why is (0 || eval) not treated as indirect in Opera?
This is simply because ECMAScript 262 3rd edition specified a somewhat odd optional exception for unusual eval() calls. See the last part of this section of the specification:
http://bclary.com/2004/11/07/#a-15.1.2.1
If value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its name as an Identifier which is the MemberExpression in a CallExpression), or if the eval property is assigned to, an EvalError exception may be thrown.
I'm not entirely sure what the reasoning behind this sentence is, but as you see both Opera's Carakan engine and Safari's ES engine have chosen to implement an exception if a reference to eval is defined on some object and called from there.
Later editions of the ECMAScript standard have removed this (having an optional exception in a spec is a very bad idea in the first place) and Opera will be adapting in some future Carakan-version. It's already been fixed internally due to these questions on StackOverflow ;)
I would guess that running:
[eval][0]('something');
would make this
be equal to the [eval]
array inside of the eval
function.
Running:
[eval][0].call(window, 'something');
should make this
be equal to the global object but I'm not sure whether or not that would work in that case for those browsers.