【问题标题】:boolean in an if statementif 语句中的布尔值
【发布时间】:2013-03-01 21:31:16
【问题描述】:

今天我得到了一个关于代码的评论,考虑到我在学校作业中检查变量是真还是假的方式。

我写的代码是这样的:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

他们说这样写会更好/更整洁:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

我得到的关于“=== true”部分的评论是,它不是必需的,可能会造成混乱。

但是我的想法是最好检查变量是否为布尔值,特别是因为 Javascript 是一种松散类型的语言。

在第二个例子中,字符串也会返回“something”;

所以我的问题;以后放开“=== true”部分是否更整洁,或者检查变量的类型是否是一种好习惯。

编辑: 在我的“真实”代码中,布尔值表示图像是否已被删除,因此 boolValue 应该具有的唯一值是 true 或 false。

例如,0 和 1 不应该在该变量中。

【问题讨论】:

  • 使用 === 是易读的好习惯
  • +1 表示=== true。避免混淆!
  • @gashu 考虑 [0] === true 评估为假。
  • @Jlange 不应该吗?请解释
  • 我的意思是,如果您只是想检查“真实”的存在,那么该语句将失败,即使它应该评估为 true( [0] 评估为 true 但不是没有类型转换)。这真的取决于你试图用你的陈述来完成什么。当您需要确保条件完全等于true 时,请使用=== true

标签: javascript semantics


【解决方案1】:

首先,事实:

if (booleanValue)

对于booleanValue 的任何真值,包括true、任何非零数字、任何非空字符串值、任何对象或数组引用等,都将满足if 语句...

另一方面:

if (booleanValue === true)

只有当booleanValue 完全等于true 时,这才会满足if 条件。没有其他真值可以满足它。

另一方面,如果你这样做:

if (someVar == true)

然后,Javascript 会做的是强制输入true 以匹配someVar 的类型,然后比较两个变量。在很多情况下,这可能不是人们想要的。因此,在大多数情况下,您希望避免使用==,因为有一组相当长的规则来说明 Javascript 如何强制将两个事物类型强制为相同类型,除非您了解所有这些规则并且可以预测 JS 解释器的所有内容当给定两种不同的类型时可能会这样做(大多数 JS 开发人员不能),您可能希望完全避免 ==

作为一个例子来说明它是多么令人困惑:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

对于2 的值,您会认为2 是一个真实值,因此它与true 相比会更好,但这不是类型强制的工作原理。它正在转换右手值以匹配左手值的类型,因此它将true 转换为数字1,因此它正在比较2 == 1,这肯定不是您想要的。

所以,买家要小心。在几乎所有情况下,最好避免使用==,除非您明确知道要比较的类型并知道所有可能的类型强制算法如何工作。


因此,这实际上取决于booleanValue 的预期值以及您希望代码如何工作。如果您事先知道它只会有一个 truefalse 值,然后将其与

显式比较
if (booleanValue === true)

只是额外的代码和不必要的

if (booleanValue)

更紧凑,可以说更清洁/更好。

另一方面,如果您不知道 booleanValue 可能是什么,并且您想测试它是否真的设置为 true 并且不允许其他自动类型转换,那么

if (booleanValue === true)

不仅是个好主意,而且是必需的。


例如,如果您查看 jQuery 中 .on() 的实现,它有一个可选的返回值。如果回调返回false,那么jQuery 将自动停止事件的传播。在这种特定情况下,由于 jQuery 只想在返回 false 时停止传播,因此他们明确检查 === false 的返回值,因为他们不想要 undefined0"" 或其他任何东西将自动类型转换为 false 也满足比较。

例如,这里是 jQuery 事件处理回调代码:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

您可以看到 jQuery 明确地寻找 ret === false

但是,考虑到代码的需要,jQuery 代码中还有许多其他地方适合进行更简单的检查。例如:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...

【讨论】:

  • 我一直在思考这个问题,但一直没有机会找到任何人问。如果你能看一看,我将不胜感激。 stackoverflow.com/questions/32615466/…
  • 这个答案并不完全正确。 'x == true' 对于非零数不会为真。
  • @Teemoh - 我不明白你的评论。见jsfiddle.net/jfriend00/89h8d8tm
  • 我只想说 'if (x)' 与 'if(x == true)' 不同,就像您在答案的第一段中所写的那样。 'if (x)' 将显式地将 'x' 转换为其布尔表示。 'if (x == true)' 将使用 EcmaScript 抽象比较算法。您写道,对于任何非零数字或非空字符串或任何对象,'if (x == true)' 都将为真。这是错误的。如果我用 2 而不是 1 运行您的示例,它将不起作用。
  • @Teemoh - 我明白你的意思。更正和澄清了答案,我添加了一个关于类型强制的部分,并附有一个示例,展示了它如何做意想不到的事情。
【解决方案2】:

如果你写:if(x === true),那么只有 x = true

如果你写:if(x),那么任何 x 都是 true,它不是:''(空字符串)、false、null、undefined、0、NaN。

【讨论】:

  • (空字符串), false, null, undefined, 0, NaN
  • 别忘了NaN-0
【解决方案3】:

在普通的“if”中,变量将被强制转换为布尔值,并在对象上使用 toBoolean:-

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, −0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

但是与 === 比较没有任何类型强制,所以它们必须相等,没有强制。

如果您说该对象甚至可能不是布尔值,那么您可能需要考虑的不仅仅是真/假。

if(x===true){
...
} else if(x===false){
....
} else {
....
}

【讨论】:

    【解决方案4】:

    这取决于您的用例。检查类型也可能有意义,但如果它只是一个标志,它就没有。

    【讨论】:

    • === 比较不执行类型强制。因此,OP 的代码确实有效地测试了标志的类型。只有当值是布尔值并且为真时,它才会成功。
    • 让我换个说法。如果你知道它是真还是假,没关系。
    【解决方案5】:

    一般来说,省略=== true会更简洁。

    但是,在 Javascript 中,这些语句是不同的。

    if (booleanValue) 将在 booleanValuetruthy 时执行——除了0false''NaNnullundefined 之外的任何内容。

    if (booleanValue === true) 只会在booleanValue 正好等于true 时执行。

    【讨论】:

    • 这正是我想要确定的,即使我只希望 boolValue 为真或假。该变量在代码中多次设置为真/假。我知道当我写代码的时候,但是如果我一年后再次检查代码,那么除非我重新阅读所有内容,否则它只是一个大问号吗?
    • @aldanux:哎呀;我的意思是''
    【解决方案6】:

    标识 (===) 运算符的行为与相等 (==) 运算符相同,只是没有进行类型转换,并且类型必须相同才能被视为相等。

    【讨论】:

    • 你最后一句话是错的。当booleanValue2 时,试试你的两个语句if (booleanValue)if (booleanValue==true)。这两个语句不会给你相同的结果。
    • 有趣。你的话我记住了。我在 ObjC/C/C++ 世界中思考,在 JS 中我假设您是正确的,因为 JS 中的数据类型可以更改,并且 2==true 不会量化 if。
    • 请参阅我上面的答案以获取此特定示例。它与 Javascript 如何进行自动类型转换以比较不同类型的两个值有关。
    【解决方案7】:

    如果变量只能接受布尔值,那么使用较短的语法是合理的。

    如果它可能被分配其他类型,并且您需要区分true1"foo",那么您必须使用=== true

    【讨论】:

      【解决方案8】:

      由于检查的值是Boolean,因此最好直接使用它来减少编码,并且完全一样==true

      【讨论】:

        【解决方案9】:

        由于您已经清楚地初始化为 bool,我认为 === 运算符不是必需的。

        【讨论】:

          【解决方案10】:

          我认为你的推理是合理的。但在实践中,我发现省略=== 比较更为常见。我认为有以下三个原因:

          1. 它通常不会增加表达式的含义 - 这是在已知值无论如何都是布尔值的情况下。
          2. 由于 JavaScript 中存在大量类型不确定性,因此当您获得意外的 undefinednull 值时,强制进行类型检查往往会让您陷入困境。通常你只是希望你的测试在这种情况下失败。 (尽管我试图平衡这种观点与“快速失败”的座右铭)。
          3. JavaScript 程序员喜欢在类型上玩得又快又松——尤其是在布尔表达式中——因为我们可以。

          考虑这个例子:

          var someString = getInput();
          var normalized = someString && trim(someString);  
          // trim() removes leading and trailing whitespace
          
          if (normalized) {
              submitInput(normalized);
          }
          

          我认为这种代码并不少见。它处理getInput() 返回undefinednull 或空字符串的情况。由于两个布尔计算 submitInput() 仅在给定的输入是包含非空白字符的字符串时才被调用。

          在 JavaScript 中,&& 如果它是假的,则返回它的第一个参数,如果第一个参数是真,则返回它的第二个参数;所以 normalized 将是 undefined 如果 someString 未定义等等。这意味着上述布尔表达式的输入实际上都不是布尔值。

          我知道很多习惯于强类型检查的程序员在看到这样的代码时会畏缩。但请注意,应用强类型可能需要明确检查 nullundefined 值,这会使代码混乱。在不需要的 JavaScript 中。

          【讨论】:

            【解决方案11】:

            在 Javascript 中,布尔值的概念相当模糊。考虑一下:

             var bool = 0 
             if(bool){..} //evaluates to false
            
             if(//uninitialized var) //evaluates to false
            

            因此,当您使用 if 语句(或任何其他控制语句)时,不必使用“布尔”类型的 var。因此,在我看来,如果你知道它是一个布尔值,那么你声明的“=== true”部分是不必要的,但如果你的值是一个模棱两可的“真实”变量,那么它是绝对必要的。有关 javscript 中布尔值的更多信息,请参阅 here

            【讨论】:

              【解决方案12】:

              这取决于。如果您担心您的变量最终可能会解析为 TRUE。然后硬检查是必须的。否则由你决定。但是,我怀疑 whatever == TRUE 语法是否会让任何知道他们在做什么的人感到困惑。

              【讨论】:

                【解决方案13】:

                修订https://www.w3schools.com/js/js_comparisons.asp

                示例:

                var p=5;
                
                p==5 ? true
                p=="5" ?  true
                p==="5" ? false
                

                === 表示相同的类型也相同的值 == 只是相同的值

                【讨论】:

                  【解决方案14】:

                  如果需要测试对象,也可以使用布尔对象进行测试 error={Boolean(errors.email)}

                  【讨论】:

                    猜你喜欢
                    • 2021-08-03
                    • 2013-03-26
                    • 2015-12-21
                    • 2018-04-17
                    • 2014-08-19
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多