Klik
Klik

Reputation: 1776

Strange result while using Javascript not operator

Before anyone jumps in to answer and bash me for asking a silly question; I'm aware of what the not operator does, at least in other languages it should invert a result from true to false and vice versa. The thing I'm stuck on is the strange behavior I get from time to time. I.e. I had this in my code. It's not doing what I expect it to do.

_checkOnOff: function(inst) {
    return (!$.suggestBox.onOff || !$.suggestBox._get(inst, 'onOff')) ?  false : true;
},

The actual values for the 'onOff' variables that I'm dealing with here are 0 and 1. I'm assuming that the '!' operator will reverse them.

However I couldn't get it to work until I changed the function to explicitly state '== 0' like so...

_checkOnOff: function(inst) {
    return ($.suggestBox.onOff == 0 || $.suggestBox._get(inst, 'onOff') == 0) ?  false : true;
},

Edit: Added info Both $.suggestBox.onOff and $.suggestBox._get(inst, 'onOff') will be either 0 or 1.

My question is why didn't !$.suggestBox.onOff produce true when $.suggestBox.onOff was equal to 0? Is Javascript ! equivalant to the bitwise operator?

Edit: Second attempt

I tried using '!!' like was suggested (to get a bool) and found nothing changed. Here is the code and outputs:

        console.log('val: ' + $.suggestBox.onOff);  // outputs: 0
        console.log('! : ' + !$.suggestBox.onOff);  // outputs: false
        console.log('!! : ' + !!$.suggestBox.onOff);   //outputs: true
        console.log('!!! : ' + !!!$.suggestBox.onOff);   //outputs: false

The output doesn't change if $.suggestBox.onOff is 1 or 0!!! it's still false, true, false. What is going on?!

Edit: Third attempt I found out that it has something to do with my variable. I don't know how, but it has to do with the way that it has been set. Ok, prepare yourselves, what I'm about to tell you, may very well blow your mind and change the way you type on the keyboard. It's that incredible:

        //this.onOff = 0;
        console.log('this.onOff: ' + this.onOff);   //output: 0
        console.log('! : ' + ! this.onOff);  //output: false
        console.log('!! : ' + !! this.onOff);   //output: true

If I uncomment out the 'this.onOff = 0', thereby explicitly assigning this.onOff to a literal, it changes the output to:

I just found out why. I will write it down in the answer section. Small clue is that it's the way the variable $.suggestBox.onOff was set.

Upvotes: 1

Views: 136

Answers (2)

Joseph Silber
Joseph Silber

Reputation: 219938

It seems that $.suggestBox.onOff is set with "0" as a string, which in JavaScript is always truthy.

Since "0" is truthy and 0 is falsy, you'd expect 0 == "0" to be false, but it's not.

Try the following in your console:

!! "0"; // true
!! 0; // false
0 == "0"; // true

Weird? Yes. Welcome to the awkward world of JavaScript!


To get around this issue, you should either have $.suggestBox.onOff be an actual number, or convert it on the fly:

_checkOnOff: function(inst) {
    return !! ( +$.suggestBox.onOff && +$.suggestBox._get(inst, 'onOff') );
}

Update: Since you pointed out in the comments that you're setting it by a text value, use this when setting it so that it's always set as a number:

$.suggestBox.onOff = +$(this).val();

Upvotes: 2

JayC
JayC

Reputation: 7141

I think you're confused, because you're negating a string, not a number. Strings are a bit different and handled a bit funny when it comes to their evaluation as a boolean.

!0

is true, as expected.

!"0"

is false... so, the question, is "0" truthy?

I wish I had a better source (sitepoint isn't bad, but it's not as authoritative as a w3 document), but, according to http://www.sitepoint.com/javascript-truthy-falsy/

The following values are always falsy:

false

0 (zero)

"" (empty string)

null

undefined NaN (a special Number value meaning Not-a-Number!)

All other values are truthy, including "0" (zero in quotes), "false" (false in quotes), empty functions, empty arrays, and empty objects.

So, what you are seeing is indeed expected.

Upvotes: 1

Related Questions