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

Boolean() vs !! #113

Open
rahulpatel opened this issue Apr 1, 2016 · 29 comments
Open

Boolean() vs !! #113

rahulpatel opened this issue Apr 1, 2016 · 29 comments

Comments

@rahulpatel
Copy link
Contributor

As the title says. Add your reaction to the one you prefer and drop a comment if you wish to give a reasoning.

@rahulpatel
Copy link
Contributor Author

Boolean()

@rahulpatel
Copy link
Contributor Author

!!

@pmcnr-hx
Copy link
Contributor

pmcnr-hx commented Apr 1, 2016

I'll take the opportunity to add the other very common case (convert a numerical string to an integer): /1 (or any or its variants) vs parseInt(..., 10).

@pmcnr-hx
Copy link
Contributor

pmcnr-hx commented Apr 1, 2016

/1 or +0 or any of the other similar variants

@pmcnr-hx
Copy link
Contributor

pmcnr-hx commented Apr 1, 2016

parseInt(..., 10)

@jamesmcneil
Copy link
Contributor

Prefer Boolean over !! as this is more easily understandable to a new starter reading our codebase for the first time. (Clarity over Brevity)

@Nick-Patrick
Copy link

I personally find !! very unreadable and looks slightly hacky. Most of us know what it means but not everyone.

Compare !!someAray to Boolean(someArray).

The difference with Boolean(something) - it's instantly readable and obvious to what it's doing.

@jameshhx
Copy link

jameshhx commented Apr 1, 2016

👍 for Boolean. It's completely clear what is happening. You could argue that it's pretty clear what !! does, but for readability and clarity, Boolean is the right choice.

@pmcnr-hx
Copy link
Contributor

pmcnr-hx commented Apr 1, 2016

clarity > brevity

@dancork
Copy link
Contributor

dancork commented Apr 4, 2016

For serverside code this makes sense but clientside code where bytes matter then !! and +0 gets my vote.

@Arditc
Copy link
Contributor

Arditc commented Apr 4, 2016

From looking at another culture repository (airbnb) https://github.com/airbnb/javascript#coercion--booleans
It seems they're happy either. So think this is more personal preference.

@pmcnr-hx
Copy link
Contributor

pmcnr-hx commented Apr 4, 2016

Don't JS compressors take care of that kind of thing for you @dancork?

@dancork
Copy link
Contributor

dancork commented Apr 4, 2016

I thought compressors/minifiers only touched arguments and scoped vars and functions.

@pmcnr-hx
Copy link
Contributor

pmcnr-hx commented Apr 5, 2016

That's probably true @dancork. I am not an expert, hence the question. UglifyJS doesn't seem to do it. However, this seemed such an obvious thing that could be automated, instead of having humans worrying about it, that I couldn't believe someone hadn't done it. The Google Closure Compiler seems to do exactly that:

var x = 0;
console.log(Boolean(x));

after running through the closure command becomes:

var x=0;console.log(!!x);

So I would argue there are options, even for the smallest possible payloads in the front-end, that don't sacrifice readability, and allow us to have a consistent coding style everywhere.
Out of curiosity, is there a reason why we are not using it?

@dancork
Copy link
Contributor

dancork commented Apr 5, 2016

That's a good shout @pmcnr-hx maybe one for a project lounge :)

@shackpank
Copy link
Member

I don't think number of characters should bear that much weight even when it's frontend code; tooling has been mentioned but also once the asset is gzip-compressed, Boolean( may end up deflated to the same number of bits as !!, is one less expression which could be better at runtime for less capable devices, and we ship a lot of library code where we're not in control of conventions like that. There are enough other confounding factors that we'd need to prove a significant performance cost before recommending code that could be considered less readable (and even then we should first look to automating it via the build process)

I've mentioned in the past the !! convention proliferated pretty widely when we were maintaining projects in ruby, php and js as it achieved the same goal in all three languages and argued for it to maintain internal consistency on projects where it's already widely used, but it's pretty clearly a "trick" rather than the idiomatic way you'd recommend writing javascript given an empty project.

@antoinerousseau
Copy link

And as such, why use parseInt() (or worst, /1 or +) when you can just use Number()

@ptcc
Copy link

ptcc commented Nov 8, 2018

@antoinerousseau those behave a little differently on the edge cases

@antoinerousseau
Copy link

@ptcc true, sometimes you need to really "parse" and sometimes you need a different base than 10, but for other cases Number() seems cleaner and clearer to me.

@ptcc
Copy link

ptcc commented Nov 10, 2018

Yes @antoinerousseau I agree!

@robertpitt
Copy link

this is my prefered way to cast a something to an integer ~~"3.04" // = 3.

Also be aware:

!!new Boolean(false) // true
!!Boolean(false) // false

@tomsoir
Copy link

tomsoir commented Oct 25, 2019

parseInt(..., 10)
Who told you guys to do so and what's wrong with Number('123')?

@pmcnr-hx
Copy link
Contributor

@tomsoir, there's nothing "wrong" with Number('123') and it's a perfectly acceptable alternative to parseInt (just less descriptive in my opinion). Consistency (if there are multiple ways to achieve the same result, stick to one) and readability are important. parseInt('123', 10) clearly describes what's happening: a string representing an integer in base 10 is being parsed into a Number primitive. I'm curious, what in your opinion is wrong with parseInt('123', 10)?

@antoinerousseau
Copy link

antoinerousseau commented Feb 13, 2020

Number() doesn't return an integer.
Number(0.1) // 0.1
parseInt(0.1) // 0

@dT-Nick yes it was worth mentioning it, althoughparseInt, as suggested by its name, is made for parsing, and stops when it encounters anything else than a digit:

parseInt("0.9") // still 0

In that case it acted like Math.trunc("0.9"), so I would recommend using Math.trunc() if you want to truncate your number, or maybe you wanted to round it, then just use Math.round(), etc. These are more adapted.

In my opinion, parseInt should only be used when you want an integer with a radix (base) different than 10. If you want a float or a regular integer, use something more explicit and adapted, and be readable for the next person who reads your code :)

And remember there is no dedicated Integer or Float types in JS, just numbers!

Read more: https://stackoverflow.com/a/20513389/1052033

@Helias
Copy link

Helias commented Oct 27, 2022

!! seems to be more efficient than new Boolean() or Boolean().

https://www.measurethat.net/Benchmarks/Show/11127/0/boolean-vs

Moreover, I am not sure that new Boolean() is more readable or understandable, you have to keep in mind that it does not convert something in the type "boolean", indeed typeof new Boolean(arr.length) is an object, it is not a boolean

image

image

while Boolean() without new returns a boolean value, but it can make a bit of confusion from my point of view

@antoinerousseau
Copy link

antoinerousseau commented Oct 27, 2022

new Boolean() is completely different and is not returning the boolean primitive we're talking about here
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/Boolean#return_value
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
TLDR; it's almost never used.

now why do you say that !! is more efficient than Boolean()? besides, most transpilers would convert Boolean() to !! anyway since it's shorter

@Helias
Copy link

Helias commented Oct 27, 2022

@levissolutions
Copy link

Old question

@mosino
Copy link

mosino commented Apr 30, 2024

They behave a bit differently in TypeScript

const a: {b?: () => void} = {b: () => {}}

if (a.b) {
  a.b(); // ok
}

if (!!a.b) {
  a.b(); // ok
}

if (Boolean(a.b)) {
  a.b(); // Cannot invoke an object which is possibly undefined
}

if (a.hasOwnProperty("b")) {
  a.b(); // Cannot invoke an object which is possibly undefined
}

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