why {}+[] returns 0?

I was scrolling up the memes channel and saw the meme bellow, I understood almost every weird syntax but… I am unable to understand two of them: why {}+[] returns 0 and why (!+[]+[]+![]).length returns 9?
No description
13 Replies
Skylark
Skylark5mo ago
Because it does
Pi (I'll eat who dont correct me
Why There must be a why
Skylark
Skylark5mo ago
It just does what it can to avoid throwing errors
Pi (I'll eat who dont correct me
Why What kind of erros Errors
Jochem
Jochem5mo ago
there are whys, but they're complicated and you need to go really deep into the design and implementation of the language. Mostly it's just best to accept that there's some quirks that will very likely never affect any code you actually write for production use ever basically any time you're relying on one of those quirks, your code is bad and needs refactoring. Or if you run into a bug introduced by one of those quirks, your code is insufficiently safe and doesn't check for errors enough
Pi (I'll eat who dont correct me
Yes, I agree. But it is fun understand some behaviors
Zoë
Zoë5mo ago
typeof NaN == "number"
This is because you get to NaN from a number, it would be weird for a number to not become a number. This is intended
9999999999999999 == 10000000000000000
This is because the 9s require 54 bits but numbers in JavaScript are 64 bit floating point numbers, so the precision is only 53 bits with the remaining bits being the exponent. This is why 2**53 == 2**53+1 but 2**53 != 2**53-1 https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats and have a look at "binary64"
0.5+0.1==0.6 0.1+0.2!=0.3
This is an error you will come across but you should avoid, never do comparisons with floating point numbers. Again and this is because the way binary encodes decimals cannot capture perfect precision. These errors can still be parsed fine, for instance 0.1 is (in binary) 0.0001100110011001100110011001100110011001100110011001101 and adding 0.5 (0.1 in binary) seems to not have as big of an effect and so can produce 0.6 but 0.2 is 0.001100110011001100110011001100110011001100110011001101 and it doesn't end up as 0.3. If working with currency use the base unit, such as cents, although errors are tiny and so passing 0.3 which behind the hood is not actually 0.3 it can safely round to 2dp and know that it should be $0.30, the problems are when you do a lot of maths with them
IEEE 754
The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard addressed many problems found in the diverse floating-point implementations that made them difficult to use reliably and portably. Many...
Zoë
Zoë5mo ago
Math.max() == -Infinity Math.min() == Infinity
When you pass arguments to these functions you can imagine that -Infinity and Infinity are the implicit first for max and min respectively, so when comparing Math.max(1,2) you're getting the max of -Infinity 1 and 2, the -Infinity is there because any other number is equal to or greater than it, and you can get it to return Infinity when passing in arrays Math.max(...arr) if arr is [] it returns a number that would work with maths that rely on it and you can also check to see if Infinity is given.
[] + [] == ""
If you were to do [1,2] + "!" you get "1,2!". What is happening is that the contents of each are being turned into strings and combined, and as they're both empty you get nothing. [1,2]+[3,4] returns 1,23,4
[] + {} == "[object Object]"
This is very similar to above, [] is turned into string "" and then {} is turned into a string [object Object] as a result. [1]+{} returns [object Object]
{} + [] == 0
This one I'm less sure about, but {} + 1 == 1, so the object becomes 0, I'm just not sure why it isn't "0"
true+true+true===3 true-true === 0 true==1
true is 1, like in most languages...
true!==1
...but it has the type boolean, not number
(!+[]+[]+![]).length == 9
+[] is 0 (using + in front of something that isn't a number to cast it to a number is useful, you may have seen +new Date() before) and as 0 is falsy if you do ! it becomes true and then +[] makes it "true" add that to ![] which is the same as !+[] which is false you get the length of "truefalse". +[] is for getting a number from the array if there is 1 number, +[2]==2, never needed it, +[1,2] is NaN.
9+"1" == "91" 91-"1" == 90
You can't subtract a string, and so it looks to see if it can convert it into a number
[]==0
As with above if you convert [] into a number it's 0
Pi (I'll eat who dont correct me
That is an awesome explanation
Zoë
Zoë5mo ago
You should never come across any of these, even the min and max ones you shouldn't come across but I have purposefully used their Infinity values Adding true values could be useful too, but I haven't needed it
Jochem
Jochem5mo ago
That's an amazing and thorough explanation, Z, thanks!
Zoë
Zoë5mo ago
My pleasure
clevermissfox
clevermissfox5mo ago
Woah thanks for this. I am really unclear on all the floating point stuff and reading this a few times has gotten me closer to understanding what you’re saying
Want results from more Discord servers?
Add your server
More Posts