Why can't you access scoped variables using eval
under a with
statement?
For example:
(function (obj) {
with (obj) {
console.log(a); // prints out obj.a
eval("console.log(a)"); // ReferenceError: a is not defined
}
})({ a: "hello" })
EDIT: As the knowledgeable CMS pointed out, this appears to be a browser bug (browsers that use the WebKit console).
If anyone was wondering what abomination I was trying to come up with that would require both the "evil" eval
and with
-- I was trying to see if I could get a function (used as a callback) executed in another context rather than the one it was defined in. And no, I probably (cough) won't use this anywhere.. more curious than anything.
(function (context,fn) {
with (context)
eval("("+fn+")()");
})({ a: "hello there" }, function () { console.log(a); })
Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!
An alternative to eval is Function() . Just like eval() , Function() takes some expression as a string for execution, except, rather than outputting the result directly, it returns an anonymous function to you that you can call. `Function() is a faster and more secure alternative to eval().
eval() is a function property of the global object. The argument of the eval() function is a string. It will evaluate the source string as a script body, which means both statements and expressions are allowed. It returns the completion value of the code.
$$eval() method. This method runs Array. from(document. querySelectorAll(selector)) within the page and passes the result as the first argument to the pageFunction .
This is a bug reproducible only from the WebKit's Console, it has problems binding the caller context when eval
is invoked from a FunctionExpression
.
When a direct call of eval
is made, the evaluated code as you expect should share both the variable environment:
(function (arg) {
return eval('arg');
})('foo');
// should return 'foo', throws a ReferenceError from the WebKit console
And also the lexical environment:
(function () {
eval('var localVar = "test"');
})();
typeof localVar; // should be 'undefined', returns 'string' on the Console
In the above function localVar
should be declared on the lexical environment of the caller, not on the global context.
For FunctionDeclaration
s the behavior is completely normal, if we try:
function test1(arg) {
return eval('arg');
}
test1('foo'); // properly returns 'foo' on the WebKit console
And
function test2() {
eval('var localVarTest = "test"');
}
test2();
typeof localVarTest; // correctly returns 'undefined'
I have been able to reproduce the problem on the following browsers running on Windows Vista SP2:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With