0

次の名前の関数を使用して、isExpressionJavaScript コードが式であるかどうかを判断しています。

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

1 つを除くすべてのテスト ケースで正しく動作します。誤って a を aFunctionDeclarationとして扱い、代わりにFunctionExpressionを返します。パーサーを書かずにこの問題を解決する方法はありますか?truefalse

4

2 に答える 2

0

@FelixKlingが指摘したように、関数が式ではなく宣言であるかどうかを判断する唯一の方法は、関数のコンテキストをチェックすることです。ただし、REPL(isExpression関数の対象)にはコンテキストがありません。したがって、問題はより単純になります。

REPLに入力されるのcodeは、キーワードで始まる場合function(最初に空白をトリミングした後)にのみ関数宣言になります。したがって、正規表現でテストできます/^\s*function\s/

@FelixKlingは、関数のコンテキストによっては、そのような関数がまだ式であり、宣言ではない可能性があることを指摘しています(つまり、関数が非ソース要素の場合、関数は式です)。ただし、codeこの関数に渡されるのはソース要素であることが保証されています。

このような関数構造を、条件演算子(eg function f() {} ? x : y)またはコンマ演算子(eg 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 に答える