MXOXW

Life always finds a way.

eval和(1, eval)的区别

| Comments

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

评论