我有一个类似于JSFiddle的工具,它允许我动态输入javascript并在页面上运行它。代码可以是多行,通常是。
不幸的是,如果我输入的代码中存在异常,如果我使用eval()来运行代码,我就无法获得异常的行号。
我找到了一个部分解决方案,而不是使用
try{
eval(code);
}
catch(e) {
processException(e);
}
改为做这样的事情:
var s = document.createElement('script');
s.appendChild(document.createTextNode(
"try{\n" +
code +
"}catch(e){processException(e)}"));
document.body.appendChild(s);
现在,如果代码抛出异常,并且我查看堆栈跟踪(在我的processException()函数中),我可以获得异常的行号(无论如何在firefox和chrome中)。
如果它实际上是一个运行时异常,例如未定义的变量,这一切都很好。问题是是否存在解析错误/语法错误,例如不匹配的parens等。我一无所获。
这有什么疯狂的解决方法,至少适用于firefox和chrome吗?在Function对象中的脚本标记内的eval内的Eval?我正在尝试一切,但没有找到任何有用的东西。
答案 0 :(得分:2)
我最终找到了一个合理的解决方案。
首先,我将window.onerror设置为某个函数。这不会获得完整的堆栈跟踪,但会获得文件和行号。
然后,我这样做:
var s = document.createElement('script');
s.appendChild(document.createTextNode(
"var someUniqueGlobalName = function () {\n" +
code +
"\n};";
document.body.appendChild(s);
请注意,这实际上不会运行我的代码,因为它只是创建一个函数(在全局范围内,名称为'someUniqueGlobalName' - 当然我每次都会提出一个不同的名称这一点)。
如果存在语法错误,它将被捕获到window.onerror函数中,我可以得到错误类型和行号(当然我必须从中减去一个,因为我添加了一行开始)。
现在,我取消了window.onerror。
最后,我通过在try / catch块中调用someUniqueGlobalName()来运行代码。如果存在运行时错误,我可以在这里获得带有行号的完整堆栈跟踪。
答案 1 :(得分:1)
您可以更进一步整合JSLINT:https://github.com/douglascrockford/JSLint
这很简单..这是一个快速测试...
下载:https://raw.github.com/douglascrockford/JSLint/master/jslint.js
jshint_test.html:
<script type="text/javascript" src="jslint.js"></script>
<script>
var result = JSLINT("var some = true;\nif (some) {");
if (result)
{
alert('Looking good');
}
else
{
var error_message = '';
for (i in JSLINT.errors)
{
var error = JSLINT.errors[i];
error_message += error.reason + ' on line: ' + error.line + ' character: ' + error.character + "\n";
}
alert(error_message);
}
</script>
查看文档。 JSLINT
的第二个参数是一个选项对象..有很多选项。
答案 2 :(得分:0)