有没有办法在JavaScript中模拟内联let表达式?



我正在编写一个从函数式语言到JavaScript的编译器。由于我的语言是基于表达式的,因此将其编译为 JavaScript 表达式也是很自然的。问题是,在编译let表达式时,我们需要能够"内联"声明和分配变量。例如:

function foo(x) {
return (let y = x * x; y);
}

显然,此代码不起作用,因为我们不能在表达式中使用let。一种解决方案是将所有内容包装在 lambda 中:

function foo(x) {
return (()=>{let y = x*x; return y})();
} 

但在某些情况下,这会产生很大的运行时成本。另一种选择是调整编译器以生成语句而不是表达式,但这将是一个不平凡的更改,如果可能的话,我宁愿避免它。

有没有办法将局部变量声明并分配给 JavaScript 作为表达式而不是没有额外运行时成本的语句?

不,没有。

您应该考虑使用标准的 lambda 演算技术,其中let x = … in …等效于(x => …)(…)。然后让编译器的另一遍删除多余的函数表达式,并在可能的情况下引入语句。

另一种方法是使用do 表达式提案中的do { let x = …; … }语法,允许您使用他们的转译器插件来生成无函数代码。

您应该避免创建新变量,而直接返回值:

function foo(x) {
return  x * x;
}

但是如果你真的需要内联一个let,这应该可以工作:

const foo = (x) => {let y=x*x;return y;}

有没有办法将局部变量声明并分配给 JavaScript 作为表达式而不是没有额外运行时成本的语句?

不是真的,但您可以将eval()与逗号运算符一起使用。我知道,我知道,eval()是邪恶的,但这是在表达式 (AFAIK( 中声明局部变量的唯一方法,尽管我不推荐它,因为引擎不会优化eval()调用。

function foo(x) {
return (eval("var y"), y = x * x, y);
}

编辑:正如Bergi指出的那样,使用let会使变量成为使用eval()执行的代码的本地变量,导致y = x * x创建一个名为y的全局变量。 应改用var

最新更新