【问题标题】:Node.js Global eval, throwing ReferenceErrorNode.js 全局评估,抛出 ReferenceError
【发布时间】:2014-08-22 17:57:55
【问题描述】:

我正在尝试从 Rhino 书中学习 JavaScript。我试图执行书中关于eval() 的以下代码。我正在使用 node.js (v0.10.29) 来执行示例。

var geval = eval;                  // aliasing eval to geval
var x = 'global';                  // two global variables
var y = 'global';

function f () {
  var x = 'local';                 // define a local variable
  eval('x += "changed";');         // direct eval sets the local variable
  return x;
}

function g () {
  var y = 'local';                 // define a local variable
  geval('y += "changed";');        // indirect eval sets global variable
  return y;
}

console.log(f(), x);               // => expected 'localchanged global'
console.log(g(), y);               // => expected 'local globalchanged'

但是,当尝试使用 geval() 别名时,我在 g() 函数中得到一个 ReferenceError

undefined:1
y += "changed";
^
ReferenceError: y is not defined
    at eval (eval at g (/Users/codematix/Learning/learnjs/expressions.js:148:3), <anonymous>:1:1)
    at eval (native)
    at g (/Users/codematix/Learning/learnjs/expressions.js:148:3)
    at Object.<anonymous> (/Users/codematix/Learning/learnjs/expressions.js:153:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16) 

据我了解,当我将 eval() 别名为 geval() 时,传递的字符串中的代码将根据 ES5 在全局范围内进行评估。但是,我遇到了ReferenceError 并且无法理解为什么。

虽然我不认为eval() 是一个关键功能,但我绝对想了解我遇到这种行为的原因。

附:当我尝试在 Google Chrome 中执行相同的代码时,它看起来就像一个魅力!奇怪!

【问题讨论】:

    标签: javascript node.js scope eval ecmascript-5


    【解决方案1】:

    问题是您从一个模块运行此代码,其中var y = global; 实际上在模块范围 中定义y,而不是全局范围。

    在浏览器中,顶级作用域是全局作用域。这意味着 在浏览器中,如果你在全局范围 var 中,某些东西会定义一个 全局变量。在 Node 中,这是不同的。顶级范围不是 全局范围; var 节点模块中的某些内容将是本地的 那个模块。

    http://nodejs.org/api/globals.html#globals_global

    因此,在 Node 中实现此功能的两种可能方法是:

    1. 在节点REPL中运行它
    2. 在模块中运行它,但将 var y = global; 替换为 y = global;

    【讨论】:

    • 因为在这种情况下,eval直接调用,所以它在定义var x = 'local'; 的同一范围内执行。(参见perfectionkills.com/global-eval-what-are-the-options 的区别在直接和间接调用eval之间。)
    • 感谢您回答问题。所以var y = 'global'; 实际上是在创建一个模块范围的变量,因此geval('y += "changed";') 实际上无法在全局范围内找到y
    • @Emmett +1,谢谢 :-)
    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    相关资源
    最近更新 更多