使用链式布尔值或三元运算符进行变量重新分配

问题描述

澄清:
这纯粹是为了实验目的,学习一门新的(对我来说)语言的怪癖、零碎和结束。如果我要与其他人分享这段代码,我当然会把它写成可读的。 :-)


我有一个函数 someFunction(x) 和两个全局变量

let m = 2;
let e = 5;

函数内部,我想检查是否x == m。如果这是真的,我想将 m 传递给辅助函数调用 (sidefunction(m)),然后将 x 重新分配给 e 以完成 someFunction

确实按预期工作:

const someFunction = x => {
    if (x == m) {
        sidefunction(m);
        x = e;
    }
    doOtherStuffWith(x);
}

但是,我想缩短它,最好是一行。这也是为了更多地了解三元和/或布尔链。

这两种方法我都试过了:

// Boolean chaining
const someFunction = x => {
    x == m && sidefunction(m) && (function () {x = e})();
    doOtherStuffWith(x);
}

没有工作,大概是因为赋值 x = e 仅适用于内部匿名函数的局部范围内的 x ...?

// Ternary operator
const someFunction = x => {
    x = (x == m && sidefunction(m)) ? e : x;
    doOtherStuffWith(x);
}

没有工作,大概是因为sidefunction(m)实际上没有被调用,出于某种原因......?

如何修复这些问题以使其正常工作?
或者,是否有其他优雅的方法可以在没有完整的多行 if 块的情况下执行此检查/调用/重新分配?

非常感谢!

解决方法

问题

x == m && sideFunction(m) && (function () {x = e})();

&& 从左到右计算,一旦找到第一个 falsey 值就会停止。除非 sideFunction 返回明确的真值,否则第三个 IIFE:

(function () {x = e})()

永远不会运行,导致 x 永远不会被重新分配。

x 在该函数中是局部的。如果您可以运行该函数,它将根据需要重新分配 x

您可以使用逗号运算符:

x == m && (sideFunction(m),x = e);

同样

x = (x == m && sideFunction(m)) ? e : x;

不会工作,因为 sideFunction 必须返回一些真实的东西才能让条件的左侧真实地评估 - 否则,x 将被分配给 x,没有变化。


所有这些都说了 - 我强烈建议不要做任何这些。您的第一种方法更具可读性,可读性比行保持重要得多。

,

您可以使用带有 comma operator 的复合表达式,而不必关心 sideFunction 的结果值。

const fn = x => (x == m && (sideFunction(m),x = e),doOtherStuffWith(x));
,

逗号运算符 , 可用于链接表达式并返回最后一个,例如,

var x = (1 + 2,10 + 2,100 + 2);
x;
//=> 102

我们可以用它来计算 sideFunction(m) 并返回 e(sideFunction(m),e)

既然你总是想执行doOtherStuffWith,你只需要弄清楚是给它e还是原来的x

const someFunction = x => doOtherStuffWith(x == m ? (sideFunction(m),e) : x);