确定 JavaScript 代码是否为表达式

Determine if JavaScript code is an expression

本文关键字:表达式 是否 代码 JavaScript 确定      更新时间:2023-09-26

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

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

它适用于所有测试用例,除了一个 - 它错误地将FunctionDeclaration视为FunctionExpression并返回true而不是false。有没有办法解决这个问题而不必编写解析器?

正如@FelixKling指出的那样,确定函数是否是声明而不是表达式的唯一方法是检查函数的上下文。但是,在 REPL(isExpression 函数适用于该 REPL)中,没有上下文。这样,事情就变得简单了。

键入到

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;
    }
}

警告:将调用字符串中的调用。这可能会使它变得不那么有用。