如何在复杂的布尔表达式上避免三元



在检查我的Javascript时,我遇到了一个关于我的复杂三元选项的no-unneeded-ternary警告。

我知道如何在简单的布尔表达式上解决这个问题:

var obvious = (1 === 1) ? true : false;
// can simply become:
var obvious = (1 === 1);

但是,在我下面的布尔表达式中,我不知道如何正确缩小范围而不担心破坏恰好非常复杂的东西:

const include =
  (options.directory && file !== '.') ? false :
  (!dotted) ? true :
  (dotted && options.all) ? true :
  (dotted && !implied && options.almostall) ? true :
  (options.directory && file === '.') ? true :
  false;

正确的速记实现是什么?


一试:

const include = !(options.directory && file !== '.') || 
  (!dotted) || 
  (dotted && options.all) ||
  (dotted && !implied && options.almostall) ||
  (options.directory && file === '.');

这是对的吗?

当您使用一堆链式三元运算符编写代码时,它会变得更加简洁且通常更难读。

const include =
  (options.directory && file !== '.') ? false :
  (!dotted) ? true :
  (dotted && options.all) ? true :
  (dotted && !implied && options.almostall) ? true :
  (options.directory && file === '.') ? true :
  false;

为了分解这一点,我将首先使用模块模式对其进行扩展:

include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    if (directory && !isDot)
        return false;
    if (!dotted)
        return true;
    if (dotted && all)
        return true;
    if (dotted && implied && almost)
        return true;
    if (directory && isDot)
        return true;
    return false;
}());

这可以简化。检查!dotted后,dotted必须为真,并且变得多余:

true && a

转换为:

a
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    if (directory && !isDot)
        return false;
    if (!dotted)
        return true;
    if (all)
        return true;
    if (implied && almost)
        return true;
    if (directory && isDot)
        return true;
    return false;
}());

作为一个足够好的人离开的问题,你可以随意在这里停下来,知道代码是简单而有效的。


答案是肯定的。。。这可以简化。最后一条if语句可以更改为return

if (a)
    return true;
return false;

转换为:

return a;
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    if (directory && !isDot)
        return false;
    if (!dotted)
        return true;
    if (all)
        return true;
    if (implied && almost)
        return true;
    return directory && isDot;
}());

当然,可以通过再次将最后一个if转换为return来简化:

if (a)
    return true;
return b;

转换为:

return a || b;
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    if (directory && !isDot)
        return false;
    if (!dotted)
        return true;
    if (all)
        return true;
    return (implied && almost) ||
        (directory && isDot);
}());

。再说一遍:

include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    if (directory && !isDot)
        return false;
    if (!dotted)
        return true;
    return (all) ||
        (implied && almost) ||
        (directory && isDot);
}());

。再说一遍:

include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    if (directory && !isDot)
        return false;
    return (!dotted) ||
        (all) ||
        (implied && almost) ||
        (directory && isDot);
}());

。再说一遍:

if (a)
    return false;
return b;

转换为:

return !a && b;
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    return !(directory && !isDot) && (
        (!dotted) ||
        (all) ||
        (implied && almost) ||
        (directory && isDot)
    );
}());

这可以通过使用德摩根定律进一步简化:

!(a && b)

转换为:

!a || !b
include = (function () {
    //set up some simple names for concepts:
    var directory = options.directory;
    var isDot = file === '.';
    var all = options.all;
    var almost = options.almostall;
    return (!directory || isDot) && (
        (!dotted) ||
        (all) ||
        (implied && almost) ||
        (directory && isDot)
    );
}());

你有它,就像逻辑所能得到的一样简单。当然,您可以选择将变量扩展回其原始定义,但我鼓励您不要这样做。实际上,我鼓励您不要简化简单的if..return语句链。

如果使代码更详细,则阅读和理解更具挑战性,这使得调试更具挑战性。很可能我在"简化"代码时在这篇文章的某个地方犯了一个错误,并且在阅读一系列&&||运算符时,如果犯了错误,并不是很明显。

最新更新