Reputation: 739
I faced with strange behaviour when using eval
in JS.
var f = function () {
var x = 10;
return function () {
eval('console.log(x);');
window['eval']('console.log(x);');
}
};
f()();
OUTPUT:
10
undefined:1
console.log(x);
^
ReferenceError: x is not defined
Why using eval
explicitly captures the x
but global['eval']
doesn't?
And even though global['eval']
doesn't capture x
, why it's unable to see after eval
, which already captured x
?
Upvotes: 7
Views: 1164
Reputation: 10548
Your inner function does not actually capture the reference of x
, and so it is never directly passed to eval
.
eval
usually works at the local scope and so the first call succeeds (because the local scope contains the declaration of x).
However, if you invoke eval in such a way that you don't have a direct reference to it, it will invoke itself in the global scope, which var x
is not a part of, and it fails.
Just don't use eval.
Upvotes: 3
Reputation: 19
window.eval work in global scope.
var variable = 1;
(function(){
var variable = 100,
cmd = "++variable";
document.write(eval(cmd)+"\n"); // increment local var 100 and output 101
document.write(window.eval(cmd)+"\n"); // increment global var 1 and output 2
})();
Upvotes: 1
Reputation: 4044
window['eval'] operates at global scope, eval() operates at local scope.
From Mozilla's Javascript reference:
If you use the eval function indirectly, by invoking it via a reference other than eval, as of ECMAScript 5 it works at global scope rather than local scope; this means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
Upvotes: 7
Reputation: 1
You can use Function.prototype.bind()
to pass x
to returned function
var f = function () {
var x = 10;
function y(n) {
eval(`console.log(${n})`);
window["eval"](`console.log(${n})`);
}
return y.bind(this, x)
};
f()();
Upvotes: 2