这是一个合适的情况,使用动态函数创建是合理的吗?

时间:2009-01-29 01:36:02

标签: javascript dynamic-function

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

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

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

<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>

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

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:1)

只要您在封闭的环境中操作,就应该工作。 Eval打开你的代码注入攻击,所以我不会把它放在一个可公开访问的网站上,但如果它完全包含在你的教室里你应该没问题。

答案 3 :(得分:1)

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

不确定这是否有帮助。

答案 4 :(得分: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将抛出propper语法错误。您可以通过(regexp)首先从用户代码中获取参数和正文然后构建它来绕过这个。但那么,这会比eval更好吗?

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

我的感觉是你现在应该和eval一起去,如果有需要的话,可以在以后更改更精细的内容。