Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The boolean "good" casting could be better #97

Closed
ghost opened this issue Nov 8, 2013 · 10 comments
Closed

The boolean "good" casting could be better #97

ghost opened this issue Nov 8, 2013 · 10 comments

Comments

@ghost
Copy link

ghost commented Nov 8, 2013

I wouldn't call this "good".

var age = 0;
//...
var hasAge = !!age;

If you think about it there is no way to cast number to truth. All numbers are equally true, they are just numbers. The logical negation operator converts from numbers to bools but this is just a dumb legacy from C where there are no real bools and convenience but has nothing to do with good practice. And further - double negation a good practice - are you serious? This damages readability so much, it could really confuse young people making them wonder if this is some kind of new operator and even experienced developers will need to think about what it does. And if you are debugging and you are in some kind of confusion already this will only add to the confusion. Then you need to be aware of all language specifics like what negation does to strings, empty strings, arrays, empty arrays, objects, empty objects, bools, numbers, specific numbers. If it was strongly typed language like C it is better because you know the type of "age", but in JS, and particularly in debugging/undocumented/confused situation you don't know the type of age and the code will produce different results.

The right thing to do would be.

// bad.. just think about it - what does "not age" even means?
// further the intention is not clear
if ( !age ) {}

// good, the intention is perfectly clear
// further the code will work even with wrong types
if ( age > 0 ) {}
if ( age !== 0 ) {}

// good
var hasAge = (age > 0);
@ssorallen
Copy link
Contributor

The example uses a Number, but the Boolean casting section is intended to be generic for any type. !!variable will cast any JavaScript type to a Boolean type.

What if age === 0 is a valid state? hasAge would be false in your example, but !!age would be true.

I agree checking values of Numbers should be done differently, but checking for truthiness is straightforward with !!.

@ghost
Copy link
Author

ghost commented Nov 8, 2013

Actually you completely missed the point. First of all if age === 0 is a
valid state you would write age >= 0, not age === 0. The actual point is
there is no conversation between any type and bool. Types are not
convertible to truth. All types are truth. Only conditions are true or
false. And further the point is about readability and expressiveness and
maintainability. But elaborating on this any further won't help, if you
don't get it from my original post you can stick with your style, I only
wanted give you some of what I know.

On Fri, Nov 8, 2013 at 4:16 AM, Ross Allen notifications@github.com wrote:

The example uses a Number, but the Boolean casting section is intended to
be generic for any type. !!variable will cast any JavaScript type to a
Boolean type.

What if age === 0 is a valid state? hasAge would be false in your
example, but !!age would be true.

I agree checking values of Numbers should be done differently, but
checking for truthiness is straightforward with !!.


Reply to this email directly or view it on GitHubhttps://github.com//issues/97#issuecomment-28027076
.

@ssorallen
Copy link
Contributor

The Boolean section is a possibly-too-abbreviated check for existence. What do you think of:

var hasAge = (age != null);

I can see how the double bang could be misinterpreted or possibly lead to the wrong value.

@serbanghita
Copy link

I agree with @bobef on " Only conditions are true or false. And further the point is about readability and expressiveness and maintainability."

Maybe the context is important, still var age = isNaN; !!age; is true and it gets confusing ... I prefer to avoid !! approach.

@jaseemabid
Copy link

+1 to avoid !!.
!!"" being false is also error prone. An empty string is not the same as having no string at all.

@goatslacker
Copy link
Collaborator

Pruning this one. Feel free to reopen if you feel strongly about it.

@ut3saturn
Copy link

Superb. Can you tell if casting is being used here? Or does this == operator have its vulnerabilities as well?

console.log(23 == "23")

Hard to tell if casting happens to the left side in order to compare it with the right. Would a true value occur?

@ljharb
Copy link
Collaborator

ljharb commented Mar 5, 2018

@ut3saturn I’m not sure what you’re asking, exactly - all == operations do type conversions. As for which side is coerced, the rules are consistent but hard to understand, which is why it’s better to make the coercion explicit and use ===.

@sstern6
Copy link
Contributor

sstern6 commented Mar 21, 2018

I was wondering what airbnb style guides thinks about the !!.

Is there a rule pref for/against:

const arr = [1,2,3];

if (!!arr.length) {
  // do something
}

To ensure the that the check for arr.length is a boolean value not a truthy or falsey value?

@ljharb
Copy link
Collaborator

ljharb commented Mar 21, 2018

@sstern6 !!x is ideal to coerce to a boolean; but https://github.com/airbnb/javascript#comparison--shortcuts already discusses that you shouldn't rely on 0 being falsy; that for "length", you should always explicitly compare to a number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants