Javascript变量捕获
Javascript variable capture
我在 JS 中使用 eval
时遇到了奇怪的行为。
var f = function () {
var x = 10;
return function () {
eval('console.log(x);');
window['eval']('console.log(x);');
}
};
f()();
输出:
10
undefined:1
console.log(x);
^
ReferenceError: x is not defined
为什么使用 eval
明确捕获 x
而 global['eval']
却没有?
即使 global['eval']
没有捕捉到 x
,为什么在已经捕捉到 x
的 eval
之后无法看到?
您的内部函数实际上并没有捕获 x
的引用,因此它永远不会直接传递给 eval
。
eval
通常工作 at the local scope 所以第一次调用成功(因为局部作用域包含 x 的声明)。
但是,如果您以没有直接引用的方式调用 eval,它将在全局范围内调用自身,var x
不属于该范围,并且它失败。
只是不要使用 eval。
您可以使用 Function.prototype.bind()
将 x
传递给返回的函数
var f = function () {
var x = 10;
function y(n) {
eval(`console.log(${n})`);
window["eval"](`console.log(${n})`);
}
return y.bind(this, x)
};
f()();
window['eval'] 在全局范围内运行,eval() 在局部范围内运行。
来自 Mozilla 的 Javascript 参考:
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
window.eval 在全局范围内工作。
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
})();
我在 JS 中使用 eval
时遇到了奇怪的行为。
var f = function () {
var x = 10;
return function () {
eval('console.log(x);');
window['eval']('console.log(x);');
}
};
f()();
输出:
10
undefined:1
console.log(x);
^
ReferenceError: x is not defined
为什么使用 eval
明确捕获 x
而 global['eval']
却没有?
即使 global['eval']
没有捕捉到 x
,为什么在已经捕捉到 x
的 eval
之后无法看到?
您的内部函数实际上并没有捕获 x
的引用,因此它永远不会直接传递给 eval
。
eval
通常工作 at the local scope 所以第一次调用成功(因为局部作用域包含 x 的声明)。
但是,如果您以没有直接引用的方式调用 eval,它将在全局范围内调用自身,var x
不属于该范围,并且它失败。
只是不要使用 eval。
您可以使用 Function.prototype.bind()
将 x
传递给返回的函数
var f = function () {
var x = 10;
function y(n) {
eval(`console.log(${n})`);
window["eval"](`console.log(${n})`);
}
return y.bind(this, x)
};
f()();
window['eval'] 在全局范围内运行,eval() 在局部范围内运行。
来自 Mozilla 的 Javascript 参考:
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
window.eval 在全局范围内工作。
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
})();