我正在寻找一种方法来获取 Javascript 中函数的返回表达式。我希望将其作为字符串获取,但任何类型都可以。另外,我正在寻找一种方法来设置函数的返回语句而不影响它的其余部分。
示例:
let f1 = () => {
let x = 1
return 2 + x
}
let f2 = () => {
let y = 2
return 3 + y
}
let s = f1.getReturnExpression()
console.log(s) // 2 + x
f2.setReturnExpression(s)
console.log(f2.toString()) // "function f2() { let y = 2; return 2 + x; }
最佳答案
提取 return 语句应该很“容易”,但我不确定如何重建一个新函数并在运行时将其分配给现有函数而不以某种方式损坏作用域。
假设现在提取 return 语句就足够了。我绝对不建议使用正则表达式或字符串操作;你只会弄错。
您应该使用类似 esprima 的工具允许您将一段代码解构为可以检查的数据结构。
给定以下函数:
function foo(x) {
if (x) {
return x + 10;
} else {
return x - 10;
}
}
将其传递给 esprima:
esprima.tokenize(foo.toString());
这就是你得到的:
[ { type: 'Keyword', value: 'function' },
{ type: 'Identifier', value: 'foo' },
{ type: 'Punctuator', value: '(' },
{ type: 'Identifier', value: 'x' },
{ type: 'Punctuator', value: ')' },
{ type: 'Punctuator', value: '{' },
{ type: 'Keyword', value: 'if' },
{ type: 'Punctuator', value: '(' },
{ type: 'Identifier', value: 'x' },
{ type: 'Punctuator', value: ')' },
{ type: 'Punctuator', value: '{' },
{ type: 'Keyword', value: 'return' },
{ type: 'Identifier', value: 'x' },
{ type: 'Punctuator', value: '+' },
{ type: 'Numeric', value: '10' },
{ type: 'Punctuator', value: ';' },
{ type: 'Punctuator', value: '}' },
{ type: 'Keyword', value: 'else' },
{ type: 'Punctuator', value: '{' },
{ type: 'Keyword', value: 'return' },
{ type: 'Identifier', value: 'x' },
{ type: 'Punctuator', value: '-' },
{ type: 'Numeric', value: '10' },
{ type: 'Punctuator', value: ';' },
{ type: 'Punctuator', value: '}' },
{ type: 'Punctuator', value: '}' } ]
这是 JavaScript 数据结构中的函数 foo
,您可以在... JavaScript 中操作它...
A m a z i n g 🤓
现在应该相当明显地弄清楚如何提取两个可能的 return
语句。
但是,值得注意的是,我确实假设每个 return
语句以分号 ;
结尾。
为了识别 return
语句的开始,我们可以编写一个 isReturnStatement
函数:
const isReturnStatement = token =>
token.type === 'Keyword' &&
token.value === 'return';
为了识别此类语句的结束,我们可以编写一个 isEndOfStatement
函数:
const isEndOfStatement = token =>
token.type === 'Punctuator' &&
token.value === ';';
正如您所看到的,您现在正在处理一个 JavaScript 数据结构,一个标记数组。每个标记代表一段代码语法。
您现在需要识别 return
语句的开始及其结束。保存并继续该过程,直到检查整个数组。
这是一种方法:
function foo(x) {
if (x) {
return x + 10;
} else {
return x - 10;
}
}
const ast = esprima.tokenize(foo.toString());
console.log(
getReturnStatements(ast)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/esprima/2.7.3/esprima.min.js"></script>
<script>
const isReturnStatement = token =>
token.type === 'Keyword' &&
token.value === 'return';
const isEndOfStatement = token =>
token.type === 'Punctuator' &&
token.value === ';';
const getReturnStatements = ast => {
const scan = ast.reduce((search, token) => {
if (isReturnStatement(token)) {
search.capture = true;
search.stmt.push('');
} else if (search.capture && !isEndOfStatement(token)) {
search.stmt[search.stmt.length - 1] += token.value;
} else {
search.capture = false;
}
return search;
}, {capture: false, stmt: []});
return scan.stmt;
};
</script>
请注意,为了提高准确性,您应该解析代码而不是对其进行标记,但我希望这给您一个足够好的开始。
关于javascript - 如何在 Javascript 中访问函数的 return 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58964832/