【问题标题】:Javascript booleans: false && true results in trueJavascript 布尔值:false && true 结果为 true
【发布时间】:2012-04-23 14:05:56
【问题描述】:

我需要根据某些单选组的值禁用/启用按钮。这些收音机由一些 groovy 代码填充,因为我正在使用 grails,这是一个 groovy 框架,它是 java 的超集。嗯,这个解释是说无线电的值被定义为布尔值,这是很自然的,因为它们对应于是/否的答案。

现在,要禁用/启用此按钮,我使用了一些 javascript,但它使用布尔值变得很糟糕。正如标题所述,在某些时候,我在一个包含 false 的变量和另一个包含 true 的变量之间进行了逻辑运算

这是有问题的代码:

var actual = true;
$('.requerido input:radio:checked').each(function() {
    console.log("actual: " + actual);
    console.log("value: " + this.value);
    console.log("actual and value: " + (actual && this.value));
    actual = actual && this.value;
    console.log("actual: " + actual);
});

如您所见,我使用 console.log 进行调试,这就是在某些时候抛出的问题:

actual: true
value: true
actual and value: true
actual: true

actual: true
value: false
actual and value: false
actual: false

actual: false
value: true
actual and value: true
actual: true

所以 true && false == false,但是 false && true == true ?请注意,这些值没有引号,因此它们是布尔值(我正在使用 Chrome 控制台进行调试,它表示双引号内的字符串,因此您可以区分 true 和“true”)。

有什么想法吗?

此外,像var x = true && false 这样的手动比较总是按预期工作,只是用变量表明问题存在。

【问题讨论】:

标签: javascript


【解决方案1】:

您选中的单选按钮输入中的this.value 实际上不是布尔值,而是一个字符串。字符串和布尔值的比较可能会导致这样的问题。使用=== 进行比较是被认为是最佳实践的原因之一。

请参阅此 SO Question 了解完整详情; JavaScript === vs == : Does it matter which “equal” operator I use?

【讨论】:

  • 如果它不是布尔值,那么我假设它被隐式转换为一个,因为控制台打印的是 true 而不是“true”或“true”。此外,当我尝试将收音机的值放入标签或所有其他 html 标记时,它不会显示,直到我明确投射 .toString()。这就是为什么我认为它是一个布尔值而不是一个字符串。
  • 我最终抛弃了布尔值并使用了数字。作为一个教训:在 js 中,当值位于 HTML 标记内时,永远不要使用布尔值。由于这个答案说明了真正的问题“实际上不是布尔值,它是一个字符串”,我将接受它(并为长时间的延迟感到抱歉)。
【解决方案2】:

请注意,&& 执行以下操作:

如果可以转换为false则返回expr1;否则,返回 expr2.

source

所以在这样的情况下:

var truish=true;//interchangeable with anything different than 0,"",false,null,undefined,NaN
var falsish=null;//interchangeable with 0,"",false,null,undefined,NaN

alert(truish&&falsish);//null (falsish was returned)

返回的值不一定是布尔值,对此的解决方案是强制布尔值!(x&&y)

所以我的猜测是这样的事情正在发生

【讨论】:

    【解决方案3】:

    如果您尝试使用逻辑运算符进行计算,请记住:

    var result = true && "false";// always results (string) "false"
    var result = true && "true";// always results (string) "true"
    var result = false && "true";// always results (boolean) false
    var result = false && "false";// always results (boolean) false
    var result = "true" && true;// always results (boolean) true
    var result = "true" && false;// always results (boolean) false
    var result = "false" && true;// always results (boolean) true
    var result = "false" && false;// always results (boolean) false
    var result = "true" && "true";// always results (string)"true"
    var result = "true" && "false";// always results (string) "false"
    var result = "false" && "true";// always results (string) "true"
    var result = "false" && "false";// always results (string) "false"
    

    因为: javascript判断第一个操作数,如果为真则返回第二个操作数,否则返回假;就像:

    var first = true
    var second = "false";
    if (first) {
        result = second;
    } else {
        result = false;
    }
    

    result = first ? second : false;
    

    这是 javascript 逻辑运算符的实际工作方式。 您必须在不同的变量类型之间进行严格的比较:

    result = true && (value==="false");
    

    strings not empty 等于 (boolean)true,甚至是“false”。

    并记住 html 元素属性是“字符串”

    【讨论】:

      【解决方案4】:

      这必须与您的单选控件的(其中一个)值有关,因为在纯 javascript 中,这会按预期计算:

      function boolx(tf,val){ 
        var test = tf && val;
        console.log([tf,val,tf && val,test]); 
      }
      tf(true,false); //=> [true,false,false,false]
      tf(false,true); //=> [false,true,false,false]
      

      也许this.value 的显式转换会有所帮助,因为this.value 实际上是一个字符串:

      var actual = true;
      $('.requerido input:radio:checked').each(function() {
          var val = /true/i.test(this.value);
          console.log("actual: " + actual);
          console.log("value: " + val);
          console.log("actual and value: " + (actual && val));
          actual = actual && val;
          console.log("actual: " + actual);
      });
      

      【讨论】:

        【解决方案5】:

        尝试按位和&&&。后者适用于条件比较,但不适用于为变量赋值。

        【讨论】:

          【解决方案6】:

          这真的是你想做的吗? :

          actual = actual && this.value;
          

          同理:

          if (actual) {
              actual = this.value;
          }
          

          actual 始终是您的代码中定义的 true,因此 actual 将是 this.value 而不是布尔值。

          【讨论】:

          • 这就是我真正在做的事情吗? actual 并不总是正确的,正如您在日志输出中看到的那样。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-08-17
          • 1970-01-01
          • 2020-12-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-06
          相关资源
          最近更新 更多