1

我可以使用 Esprima 和 Acorn 解析箭头函数,但使用普通函数会出错:

const esprima = require('esprima');
const acorn = require('acorn');

console.log(esprima.parseScript(` () => { console.log('Test')}`)); //works
console.log(acorn.parse(` () => { console.log('Test') }`); //works

console.log(esprima.parseScript(`function () { console.log('Test')}`)); // Unexpected token
console.log(acorn.parse(`function () { console.log('Test') }`); //Unexpected token

有什么建议么?

4

1 回答 1

4

tl;博士

如果该行以标记开头function,则它是FunctionDeclaration,而不是FunctionExpression。并且函数声明需要一个标识符(在FunctionExpression中 它是可选的)。

--------

function () { console.log('Test') }编写代码的方式使其成为函数声明FunctionDeclaration,而不是函数表达式。并且函数声明需要一个标识符(在函数表达式中它是可选的)。

在 Chrome 控制台中尝试,你会得到同样的错误。

要理解,您必须查看语法 os ES6(更多内容见下文)。

( ArrowFunction )始终() => {}是一个表达式(具体来说,信不信由你,一个AssignmentExpression)。


一个 JavaScript,在 ES6 中,Script大致是一个语句序列(StatementList,它是StatementListItem的序列)。

StatementListItemStatementDeclaration。_

StatementDeclaration之间,唯一可能的表达式是 ExpressionStatement

ExpressionStatement只不过是一个Expression

Expression中,您可以找到FunctionExpression

因为它们以相同的标记开头,所以我相信FunctionDeclaration优先于FunctionExpression(前者在语法中“不那么深入”)。因此解析器使用令牌function并期望FunctionDeclaration继续,抛出错误。


摆脱错误

您可以添加一个标识符,满足FunctionDeclaration的要求:

console.log(esprima.parseScript(`function test() { console.log('Test')}`));
console.log(acorn.parse(`function test() { console.log('Test') }`);

但是,这又使它成为一个 FunctionDeclaration。要使您的代码单独成为函数表达式,正如@JaredSmith注释中指出的那样,请将其包装到(/ )s 中:

console.log(esprima.parseScript(`(function () { console.log('Test')} )`));
console.log(acorn.parse(`(function () { console.log('Test') } )`);
于 2018-03-29T19:54:35.907 回答