Javascript 在一次尝试/捕获中评估犀牛身上的虫子

Javascript 在一次尝试/捕获中评估犀牛身上的虫子,javascript,eval,rhino,Javascript,Eval,Rhino,好的,我想我在犀牛身上发现了一只虫子。我试图在全局范围内动态地评估代码,如果我只执行eval.call(null,“代码到评估”);在我试图捕捉异常之前,一切都很顺利。当我用try/catch包围代码时,代码实际上并没有在全局上下文中进行评估 要说明错误,请执行以下操作: function works(str) { eval.call(null, str); } function doesntWork(str, count) { try { eval.call(null, st

好的,我想我在犀牛身上发现了一只虫子。我试图在全局范围内动态地评估代码,如果我只执行eval.call(null,“代码到评估”);在我试图捕捉异常之前,一切都很顺利。当我用try/catch包围代码时,代码实际上并没有在全局上下文中进行评估

要说明错误,请执行以下操作:

function works(str) {
  eval.call(null, str);
}

function doesntWork(str, count) {
  try {
    eval.call(null, str);
  } catch (e) {
    println('Error in ' + count + ' call: ' + e);
  }
}

works('var abc = 123;');
works('println("The value: " + abc);');
doesntWork('var xyz = 123;', 'first');
doesntWork('println("The value: " + xyz);', 'second');
当我在内置于OpenJDK 6的Rhino中运行此程序时,我得到:

The value: 123
Error in second call: ReferenceError: "xyz" is not defined.
当我将println改为console.log并在Chrome中运行它时,我更确信这是一个bug,这时我得到了2“the value:123”的日志,这是我所期望的

此外,我查了一下,得到了:

10.4.2输入评估代码

以下步骤在以下情况下执行: 控件进入执行上下文 对于评估代码:

  • 如果没有调用上下文,或者如果评估代码不是 通过直接呼叫进行评估 (15.1.2.1.1)至评估功能 那么,
  • 将执行上下文初始化为全局执行 使用评估代码作为C作为上下文 如10.4.1.1所述
  • 否则,,
  • 将ThisBinding设置为与的ThisBinding相同的值 调用执行上下文
  • 将LexicalEnvironment设置为与LexicalEnvironment相同的值 调用执行上下文的
  • 将VariableEnvironment设置为与 呼叫的可变环境 执行上下文
  • 如果评估代码为严格代码,则
  • 让strictVarEnv成为调用NewDeclarativeEnvironment的结果 将LexicalEnvironment作为 争论
  • 将LexicalEnvironment设置为strictVarEnv
  • 将VariableEnvironment设置为strictVarEnv
  • 按照10.5所述执行声明绑定实例化 使用eval代码
  • 第一点是我的情况,或者说“没有调用上下文”,所以这应该在全局上下文中进行评估,我的xyz变量应该可以正常工作


    我是真的遇到了Rhino bug,还是遗漏了什么?

    JDK中内置的Rhino代码非常非常古老,它有很多bug,在Mozilla当前版本的软件中已经修复(很长时间)


    如果您正在启动一个新项目,我强烈建议您只使用来自Mozilla的代码来集成Rhino,并且只需相信1.6中的所有“ScriptEngine”内容都不存在(或者,可能,围绕Mozilla内容实现您自己的ScriptEngine代码)。不要犯我犯的同样的错误。两次-(

    bummer,这是有道理的。顺便说一句,这个问题有一个简单的解决方法…将eval调用拉到它自己的函数,它没有一个try/catch…尽管不幸的是,这对于JDK Rhino是必要的