0

我正在使用以下命名的函数isExpression来确定某些 JavaScript 代码是否是表达式:

function isExpression(code) {
    try {
        new Function("return " + code);
        return true;
    } catch (e) {
        return false;
    }
}

它适用于除一个之外的所有测试用例 - 它错误地将 aFunctionDeclaration视为 aFunctionExpression并返回true而不是false. 有什么方法可以解决这个问题而无需编写解析器?

4

2 回答 2

0

正如@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/));
于 2012-08-13T16:05:00.803 回答
-1

通过检查构造函数返回的值的类型,我们可以确定原始表达式是一个函数。

function isExpression(code) {
    try {
        return typeof (new Function("return " + code)) () !== 'function';
    } catch (e) {
        return false;
    }
}

警告:将调用字符串中的调用。这可能会降低它的用处。

于 2012-08-12T14:37:31.673 回答