正如@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/));