eval直接调用时,使用调用时的作用域
eval间接调用时,使用全局作用域
1 2 3 4 5 6 7
| var x = 1; function test(){ var x = 2; eval('console.log("x: " + x)'); (1, eval)('console.log("x: " + x)'); } test();
|
一些间接调用的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13
| (1, eval)('...') (eval, eval)('...') (1 ? eval : 0)('...') (__ = eval)('...') var e = eval; e('...') (function(e) { e('...') })(eval) (function(e) { return e })(eval)('...') (function() { arguments[0]('...') })(eval) this.eval('...') this['eval']('...') [eval][0]('...') eval.call(this, '...') eval('eval')('...')
|
直接调用的例子:
1 2 3 4 5 6 7 8
| eval('...') (eval)('...') (((eval)))('...') (function() { return eval('...') })() eval('eval("...")') (function(eval) { return eval('...'); })(eval) with({ eval: eval }) eval('...') with(window) eval('...')
|
ES5直接调用定义的第一段里 - 是这样一个事实:调用表达式里的 “eval”应当是引用,而不是值
1 2 3 4 5
| eval(); // <-- 调用括号左边的表达式 — "eval" — 计算出一个引用 (eval)(); // <-- 调用括号左边的表达式 — "(eval)" — 计算出一个引用 (((eval)))(); // <-- 调用括号左边的表达式 — "(((eval)))" — 计算出一个引用 (1,eval)(); // <-- 调用括号左边的表达式 — "(1, eval)" — 计算出一个值 (eval = eval)(); // <-- 调用括号左边的表达式 — "(eval = eval)" — 计算出一个值
|
参考:
eval 的一些不为人知道的用法 - 开源中国社区
Global eval. What are the options? — Perfection Kills