1

我目前正在开发一个教程网站,用于教授 Web 开发的基础知识(HTML、CSS 和 JavaScript,对于初学者)。我想要一个可以深入涵盖各种主题的设置,然后提供一个基本的沙盒环境,用户可以在其中编写代码来解决每个教程部分末尾提出的问题。

例如,如果我在之前的教程中介绍了乘法,并且用户刚刚完成了有关能够返回值的函数的课程,我可能会要求他们提交一个返回两个参数乘积的函数。

这不是使用动态函数创建被认为是一个好主意的完美实例吗?让我们看一个例子。

<script>
function check()
 {
eval('var f = ' + document.getElementById('user_code').value);
if (f(5, 10) == 50)
 {
// user properly wrote a function which
// returned the product of its parameters
 }
 }
</script>

这是一个坏主意吗?如果是这样,请解释一下。

4

5 回答 5

1

听起来您想重新制作Firebug甚至是 IE8 中的新开发者工具。因此,我不得不说从来没有一个有用的案例。更不用说如果这个网站公开了脚本注入的可能性。

于 2009-01-29T01:54:17.113 回答
1

这听起来像它可以工作。但是,您的环境中最大的挑战可能是错误处理。学生肯定会犯各种错误:

  • 编译时错误,将在eval()
  • 运行时错误,将在您调用函数时检测到
  • 无法检测到的运行时错误,例如无限循环或堆栈溢出

更精细的方法可能会将输入的 Javascript 解析为解析树表示,然后将其与预期的解析树进行比较。如果不匹配,请指出可能出错的地方并让学生再试一次。如果它确实匹配,那么您可以eval()调用该函数,知道它会按照您的预期进行。

在 Javascript 中为 Javascript 实现词法分析器和解析器将具有挑战性,但肯定不是不可能的。

于 2009-01-29T02:22:28.227 回答
1

只要您在封闭环境中操作它就应该可以工作。Eval 让您面临代码注入攻击,因此我不会将其放在可公开访问的网站上,但如果它完全包含在您的教室中,您应该没问题。

于 2009-01-29T02:26:35.660 回答
1

该代码可以工作,但如果在语法或其他方面都存在错误怎么办?也许使用 try 块来捕获任何错误并将其显示给用户会有所帮助......

不确定这是否有帮助。

于 2009-01-29T02:32:01.390 回答
1

在你的情况下,我觉得这没有什么问题。或者,您可以使用new Function()先构建东西然后运行它来运行代码。理论上,这会将“编译”和执行的阶段分开。但是eval,将首先检查代码并抛出错误:

var usercode = document.getElementById('user_code').value;
try {

  var f = new Function( 'a','b','return (' + usercode + ')(a,b);' );
  if ( f( 5, 10 ) ) {
    // user properly wrote a function which
    // returned the product of its parameters
  }
  else {
    // user wrote code that ran but produced incorrect results
  }

}
catch ( ex ) {
  // user wrote something really bad
}

以这种方式做事的问题是抛出的异常可能是无意义的。"foo;;=bar"将在括号中报告“缺少 )”错误,而 eval 将引发适当的语法错误。您可以通过(正则表达式)首先从用户代码中获取参数和主体然后构建它来绕过它。但是,这会比一个更好eval吗?

我认为您真正的问题是帮助用户避免隐式全局变量的陷阱。您将如何帮助用户避免编写由于第一次设置全局而仅在第二次运行时才有效的代码?您不需要每次运行都实现一个干净的沙箱吗?我会看看 jsbin.com、firebug 和类似工具是如何处理这些事情的。

My feeling is that you should go with eval for now and change it for more elaborate stuff later if the need arrises.

于 2009-01-29T02:35:57.713 回答