Javascript booleans: false && true results in true

10,293

Solution 1

The this.value from your checked radio button input is not actually a boolean it is a string. The comparison of strings and boolean values can cause issues like this. It is one of the reasons why it is considered best practise is to use === for comparison.

See this SO Question for full details; JavaScript === vs == : Does it matter which “equal” operator I use?

Solution 2

Note that the && does the following:

Returns expr1 if it can be converted to false; otherwise, returns expr2.

source

So in cases like:

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)

The returned value isn't necessarily a boolean, a solution to this would be to force a boolean !(x&&y)

So my guess is that something like this is happening

Solution 3

if you are trying to calculate with logic operators, remember:

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"

because: javascript judge the first operand, if true it will return the second operand, or else return false; it just like:

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

or

result = first ? second : false;

this is the way javascript logic operator actually works. you must perform strict comparison between different variable types:

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

strings not empty is equal to (boolean)true, even "false".

and remember that html element attributes are "String"s

Solution 4

This must have to do something with (one of) the values of your radio controls, because in plain javascript this evaluates as expected:

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]

Maybe an explicit conversion of this.value helps, because this.value is actually a string:

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);
});
Share:
10,293
GalmWing
Author by

GalmWing

Updated on June 17, 2022

Comments

  • GalmWing
    GalmWing about 2 years

    I need to disable/enable a button depending in on the value of some radio groups. These radios are populated by some groovy code becasue I'm using grails, a framework for groovy, that is a superset of java. Well that explanation was to say that the values of the radios are defined as booleans, which is just natural because they correspond to yes/no answers.

    Now, to disable/enable this button I use some javascript, but it goes bananas with boolean values. As the title states, on some point I do a logical and between a variable that holds false and another variable that holds true

    Here is the peice of problematic code:

    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);
    });
    

    As you can see I use the console.log for debugging, and this is what throws at some point:

    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
    

    So true && false == false, but false && true == true ? Note that the values have no quotes, so they are boolean values (I'm debugging using the Chrome console which represent strings inside double quotes, so you can distinguish between true and "true").

    Any ideas?

    Also, doing a manual comparison like var x = true && false always works as expected, is juts with variables that the problem is present.

  • GalmWing
    GalmWing about 12 years
    if it is not a boolean then I assume that it is implicitly converted to one, because the console prints true and not "true" or 'true'. Also when I try to put the value of the radio inside a label or every other html tag, it is not displayed until I explicitly cast .toString(). That is why I assumed it was a boolean and not a string.
  • GalmWing
    GalmWing about 12 years
    Is that what I'm actually doing? actual is NOT always true, as you can see in the log output.
  • GalmWing
    GalmWing over 11 years
    I ended up tossing away the booleans and used numbers instead. As a lesson: in js never use booleans when a value resides inside a HTML tag. Since this answer states the real problem "is not actually a boolean it is a string", I'm going to accept it (and sorry for the loooong delay).