Odd JavaScript, destructured, part 1

Joseph Chamochumbi
4 min readSep 9, 2018

--

Recently I came across the following video. Needless to say, as a JavaScript advocate, I felt I had to understand every little quirk demonstrated.

Let’s do this!

“Learning together to be better developers!” by rawpixel on Unsplash

JavaScript can’t handle numbers?

Right off the bat, the speaker hits us with a stone. JavaScript can’t be consistent with numbers. It can handle 10 or 15, but it can’t stay consistent when a 0 is prefixed. What is going on?

$ node
>10
10
>15
15
>015
13

This one is quite simple.

In JavaScript octal number syntax uses leading zeroes, with a gotcha:

>0777 // Is taken as octal
481
>0999 // Is not taken as octal
999

It must be obvious by now why this happens. The digit 9, or any digit greater than or equal to 8, does not exist in the octal numeral system. So 015 is in fact, an octal representation of 13 decimal.

One must remember that strict mode and ES6, forbid this syntax, which is instead replaced by 0o.

Nothing is magically known, therefore here is my source.

JavaScript can’t handle large numbers?

Alright, fair enough, 45 seconds into the video and the speaker has now given us a really hard one, because it is true.

Large numbers arithmetic does break down in JavaScript. However, we must be able to understand what is happening, it can’t just be that JavaScript is producing off-by-one errors.

It all boils down to powers of 2. To be exact, the 53rd power of 2.

> Math.pow(2,53)
9007199254740992

Recognize that number? A side from the speaker using this syntax, we have the same number. This is a 53 bits number, and it is the largest that JavaScript can handle while also being arithmetically accurate.

Nevertheless, JavaScript will not overflow or crash when numbers are added to this 53 bit monster. In this case, adding 1 to Math.pow(2,53) is creating a 54th bit, that is multiplying by 2 once again,which is causes problems to JavaScript. From this point forward, arithmetic behaves rather strange.

More information here.

Greater, less, than or equally illogical

Now the speaker claims that JavaScript lacks algebraic properties.

What’s just happening here then?

> 0 <= null
true
> 0 >= null
true

Then null equals zero right? Wrong.

> 0 == null
false
> 0 === null
false

Even the almighty strict equality seems to fail. Here we have a typical case of, You Don’t Know JS.

Abstract Relational Comparison, performs implicit coercion differently than Loose Equals or Strict Equals, because Abstract Relation Comparison first checks if the values are of type string, if not then it casts them to number, where null is coerced to zero.

Equality coerces null to undefined, because it does to number coercion on Strings, Boolean, and well, Numbers. To coerce null to a number in equality check, prefix + to it.

> 0 === +null
true

So ≤ and ≥ coerce null to zero, because these first check type of null, since it is not a string, then null is coerced to number zero, while == and ===, do not apply to number coercion on null, casting it to undefined, which is not equal to zero.

Objects are never the same, unless they actually are

The next section is perhaps one of the most valuable take-away from the video.

In JavaScript, you should not expect object equality, ever. This is also true for arrays, and dates, which are object-like.

In essence, for objects-like, Strict Equals and Lose Equals check memory references. See:

> const obj = {id: 0, name: 'Joseph'}
> const notObj = {id:0, name: 'Joseph'}
> const objRef = obj;
> obj === notObj
false
> obj === objRef
true

In the above snippet, obj and objRef share the same memory reference. If you change somehow objRef, then obj will also be changed.

> objRef.age = 20                               
20
> obj
{ id: 0, name: 'Joseph', age: 20 }

Just think about this, to make objRef equal to obj you actually did do the assignment!

Evaluating object equality is quite a complex subject. You can take the approach of checking getOwnPropertyNames on the two objects to compare, each property, but if these are also objects, or functions, you’ll start to run into edge cases which are most likely not your main problem.

That’s it for now, in the next section we’ll explore array holes, sort default behavior, bit-wise operations and tricks to generate weird returns.

--

--

Joseph Chamochumbi

Señor Developer. I do full-stack with JS & TS. Currently mastering Rust.