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 明确捕获 xglobal['eval'] 却没有? 即使 global['eval'] 没有捕捉到 x,为什么在已经捕捉到 xeval 之后无法看到?

您的内部函数实际上并没有捕获 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
})();