Open rahulpatel opened 8 years ago
Boolean()
!!
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)
.
/1
or +0
or any of the other similar variants
parseInt(..., 10)
Prefer Boolean
over !!
as this is more easily understandable to a new starter reading our codebase for the first time. (Clarity over Brevity)
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.
:+1: 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.
clarity > brevity
For serverside code this makes sense but clientside code where bytes matter then !!
and +0
gets my vote.
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.
Don't JS compressors take care of that kind of thing for you @dancork?
I thought compressors/minifiers only touched arguments and scoped vars and functions.
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?
That's a good shout @pmcnr-hx maybe one for a project lounge :)
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.
And as such, why use parseInt()
(or worst, /1
or +
) when you can just use Number()
@antoinerousseau those behave a little differently on the edge cases
@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.
Yes @antoinerousseau I agree!
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
parseInt(..., 10)
Who told you guys to do so and what's wrong withNumber('123')
?
@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)
?
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
!!
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
while Boolean()
without new
returns a boolean
value, but it can make a bit of confusion from my point of view
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
for the benchmark here https://www.measurethat.net/Benchmarks/Show/11127/0/boolean-vs
Old question
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
}
As the title says. Add your reaction to the one you prefer and drop a comment if you wish to give a reasoning.