全局作用域 eval

eval是在caller的作用域里运行传给它的代码:

var x = 'outer';
  (function() {
    var x = 'inner';
    eval('x'); // "inner"
  })();
 
在 ES5,可以分为direct调用或者indirect调用,和是否在strict模式调用
 
(1,eval)('1+1')  为indirect调用,(1,eval)仍然返回一个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')('...')
 
只有在eval指向standard, built-in function(eval没有被覆盖或者不是复制品),才是direct调用:
eval = (function(eval) {
    return function(expr) {
      return eval(expr);
    };
  })(eval);
 
  eval('1+1'); // It looks like a direct call, but really is an indirect one.   It's because `eval` resolves to a custom function, rather than standard, built-in one
 
下面这些都是direct调用:
  eval('...')
  (eval)('...')
  (((eval)))('...')
  (function() { return eval('...') })()
  eval('eval("...")')
  (function(eval) { return eval('...'); })(eval)
  with({ eval: eval }) eval('...')
  with(window) eval('...')
 
eval是引用指针的话,都为直接调用,如果为值的话,为间接调用
eval('1+1')这里的eval是引用,需要被执行,执行之后就是一个标准的,内置的 function对象
(1,eval)('1+1')的话,(1,eval)执行结果为一个值,不是一个引用
(eval)执行结果仍然为一个引用,不是值,因为小括号不会执行它里面的表达式(does not evaluate its expression),所以传一个引用进去,返回的仍然是引用
 
 
原文地址:https://www.cnblogs.com/chuangweili/p/5166414.html