【发布时间】:2011-05-11 10:53:35
【问题描述】:
当 JavaScript 引擎在解析代码时遇到不符合语言语法的记号或记号顺序时,会抛出 SyntaxError。
但如果出现语法错误,程序怎么可能一开始就运行呢?
如何捕捉 JavaScript 语法错误?
【问题讨论】:
标签: javascript
当 JavaScript 引擎在解析代码时遇到不符合语言语法的记号或记号顺序时,会抛出 SyntaxError。
但如果出现语法错误,程序怎么可能一开始就运行呢?
如何捕捉 JavaScript 语法错误?
【问题讨论】:
标签: javascript
您不能使用try-catch 块来处理语法错误,因为它们是在解析代码而不是在运行时抛出的。
但是,您可以使用 window.onerror 并找出错误。您必须确保onerror 函数是在单独的脚本标签中定义的,而不是在可能存在错误的标签中!
例如:
这不起作用,因为抛出错误时脚本尚未开始运行:
<script>
window.onerror = function (e) {
console.log('Error: ', e);
};
console.log('a'');
</script>
这将起作用:
<script>
window.onerror = function (e) {
console.log('Error: ', e);
};
</script>
<script>
console.log('a'');
</script>
【讨论】:
可以使用 try-catch 捕获的是运行时错误,而不是语法错误(如果您 eval 您的代码您可以处理评估代码中的语法错误,但这很奇怪)。
我建议您阅读以下内容:
【讨论】:
在 JS 世界中,SyntaxError 可以是运行时异常。例如,当尝试解析非 JSON 格式的 JSON 响应时,可能会出现这种情况。服务器可以发回多种类型的响应,因此如果您向您的请求发送一个 HTML 主体响应,该响应期望在主体中包含 JSON,您将在 JS 中得到一个SyntaxError。在这种情况下,您会收到类似于以下内容的错误消息:SyntaxError: JSON Parse error: Unrecognized token '<'。
但您也可能会遇到其他运行时语法错误。 Mozilla 在此处列出了一些列表:SyntaxErrors for JSON parsing
您可能希望在代码中捕获这些。您可以使用这样的通用 try/catch 块来执行此操作:
try {
JSON.parse('<html></html>');
} catch (e) {
console.log("I catch & handle all errors the same way.");
}
或者您可以专门查找 SyntaxError:
try {
JSON.parse('<html></html>');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("I caught a pesky SyntaxError! I'll handle it specifically here.");
} else {
console.log("I caught an error, but it wasn't a SyntaxError. I handle all non-SyntaxErrors here.");
}
}
Mozilla 拥有更多 info on JS errors and handling them。
【讨论】:
SyntaxError 在语言意义上并不是真正的语法错误(例如:您用引号开始了一个字符串,但在任何地方都没有右引号等)。后者确实抓不住。 SyntaxError 实际上只是一个运行时错误。不幸的是,它的名字令人困惑。
您可以捕获 程序员生成的和运行时异常,但您无法捕获 JavaScript 语法错误,可能会在某些浏览器中使用 window.onerror 处理它们。
这摘自我非常喜欢的书JavaScript- The Complete Reference by Thomas-Powell。您可以参考该书中的代码示例。
【讨论】:
您无法捕获解析器生成的语法错误,因为它们是由解析器抛出的,它不知道 try/catch 块的作用。更多信息 - Learning how programming languages work
有一种方法可以捕获在代码执行期间生成的语法错误。这种方法很慢,我不推荐它。您可以使用 eval() 捕获 SyntaxErrors。
var code = `function() {
doSomething()
somethingElse()
var x = 5 + 5
// No ending curly brace` // The code to be run using eval
try {
eval(code) // Try evaluating the code
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
console.log('A SyntaxError has been caught\n\nDetails:\n' + e) // It is a SyntaxError
}
或者,您可以使用 new Function(),它的速度提高了 93% - https://jsben.ch/1HLQ1
var code = `function() {
doSomething()
somethingElse()
var x = 5 + 5
// No ending curly brace` // The code to be run using eval
try {
new Function([], code) // Try evaluating the code
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
console.log('A SyntaxError has been caught\n\nDetails:\n' + e) // It is a SyntaxError
}
【讨论】: