我使用以下名为
isExpression
的函数来确定某些 JavaScript 代码是否是表达式:
function isExpression(code) {
try {
new Function("return " + code);
return true;
} catch (e) {
return false;
}
}
它适用于除一个测试用例之外的所有测试用例 - 它错误地将
FunctionDeclaration
视为 FunctionExpression
并返回 true
而不是 false
。有没有什么方法可以解决这个问题而无需编写解析器?
正如 @FelixKling 指出的,确定函数是否是声明而不是表达式的唯一方法是检查函数的上下文。然而,在 REPL 中(
isExpression
函数的目的)没有上下文。这样事情就变得简单了。
输入到 REPL 中的
code
只能是函数声明,如果它以关键字 function
开头(在修剪开头的空格之后)。因此可以通过正则表达式/^\s*function\s/
来测试。
@FelixKling 指出,这样的函数可能仍然是一个表达式,而不是一个声明,具体取决于函数的上下文(即,如果它是一个“非源元素”,则该函数是一个表达式)。然而,传递给此函数的 code
保证是源元素。
如果这样的函数构造要用作使用条件运算符(例如
function f() {} ? x : y
)或使用逗号运算符(例如
function f() {}, x
)的表达式,则 isExpression
仍将返回 false
。然而这样的代码会引发SyntaxError
。因此,以下 isExpression
的实现将正确测试某些代码是否是所有情况下的表达式:var isExpression = function (functionDeclaration) {
return function (code) {
if (functionDeclaration.test(code)) return false;
try {
Function("return " + code);
return true;
} catch (error) {
return false;
}
};
}(new RegExp(/^\s*function\s/));
function isExpression(code) {
try {
return typeof (new Function("return " + code)) () !== 'function';
} catch (e) {
return false;
}
}
警告:将调用字符串中的调用。这可能会降低它的用处。