Numbers in JavaScript
lol
A dive into types, equality, and ECMAScript 2016 specifications
About This Talk
- Highly technical
- Largely frivolous
- (Almost) never should affect your day-to-day life
- Doesn't actually have the answers to my questions
- Might still be kind of fun
About Me
- Bobby Grayson
- @yburyug
- Normally Known As Red Leather Pants Here
- Dev @ Cometa Works
- Likes cats
Welp, let's go...
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122484/Screen_Shot_2016-10-16_at_5.25.26_PM.png)
So the other day I saw something weird
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3120060/Screen_Shot_2016-10-15_at_7.24.52_PM.png)
Someone shared this code snipped from V8
Programmers only ever pick arbitrary numbers that are powers of 2
Hmmm
*spelunking begins*
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3120099/Screen_Shot_2016-10-15_at_8.24.42_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3120061/Screen_Shot_2016-10-15_at_7.26.40_PM.png)
I've never seen a -0 before...
> -0 === 0 // I always start with strict equality, because JS
true
> -0 == 0 // As expected
true
> -0 == +0 // Alright....maybe its just because `==`
true
> -0 === +0 // Well...shit
true
> -0 / 0 // Reasonable
NaN
> -0 / 1 // Okay..
-0
> 1 / -0 // as expected
-Infinity
> 1 / +0 // Normal Enough
Infinity
> +0 == 0 // Alright, the inverse of our first bit works
true
> +0 === 0 // And confirms itself.
true
Let's play in the console
Takeaways
- It seems like +0 is aliased to 0
- It seems like they all behave the same
- I'm sure this isnt truly the case
Let's go a little deeper
Enter `Object.is`
> Object.is(-0, +0) // Well, shit
false
> Object.is(-0, -0) // Well, this is reasonable
true
> Object.is(-0, 0) // Hmmmm
false
> Object.is(+0, 0) // It seems `0` _really_ is aliased as `+0`
true
- both arguments are Undefined
- both arguments are Null
- both arguments are True or both False
- both arguments are String primitives of the same length with the same characters
- both arguments are the same Object
-
both arguments are Number types and
- both arguments are +0
- both arguments are -0
- both arguments are NaN
- or both arguments are non-zero and both not NaN and both have the same value
Object.is Rules
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122368/Screen_Shot_2016-10-16_at_4.40.10_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122371/Screen_Shot_2016-10-16_at_4.41.21_PM.png)
vs ==
This is not the same as being equal according to the == operator. The == operator applies various coercions to both sides (if they are not the same Type) before testing for equality (resulting in such behavior as "" == false being true), but Object.is doesn't coerce either value.
vs ===
This is also not the same as being equal according to the === operator. The === operator (and the == operator as well) treats the number values -0 and +0 as equal and treats Number.NaN as not equal to NaN.
More Object.is Rules
An Aside: Lol Coercion
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122412/Screen_Shot_2016-10-16_at_4.55.30_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122414/Screen_Shot_2016-10-16_at_4.56.38_PM.png)
Some Observations Before Going Further
- It says 'number types', not objects
- Numbers are a primitive, right?
- Primitives arent objects, right?
- This is clearly just gonna keep getting weirder
Number Specification Overview
JavaScript Primitves
- Boolean
- String
- Null
- Undefined
- Symbol
- Number
JavaScript Primitves
- Boolean
- String
- Null
- Undefined
- Symbol
- Number
From the spec:
4.3.2 primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6.
NOTE:
A primitive value is a datum that is represented directly at the lowest level of the language implementation.
From the `Number` Overview
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122438/Screen_Shot_2016-10-16_at_5.10.19_PM.png)
> new Number
[Number: 0]
> new Number(-0)
[Number: -0]
> new Number(+0)
[Number: 0]
> new Number(0)
[Number: 0]
> one = new Number(1)
[Number: 1]
> one == 1
true
> one === 1
true
> Object.is(one, 1)
false
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122442/Screen_Shot_2016-10-16_at_5.12.23_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122445/Screen_Shot_2016-10-16_at_5.12.28_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122444/Screen_Shot_2016-10-16_at_5.12.35_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122447/Screen_Shot_2016-10-16_at_5.12.41_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122448/Screen_Shot_2016-10-16_at_5.12.50_PM.png)
The Full Number Specification
Per ECMAScript 2016
Some Interesting Points
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122727/Screen_Shot_2016-10-16_at_6.56.10_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122730/Screen_Shot_2016-10-16_at_6.56.58_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122733/Screen_Shot_2016-10-16_at_6.59.46_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122737/Screen_Shot_2016-10-16_at_6.59.26_PM.png)
Note that...
- The spec keeps saying 'integer', but everything is floats per the IEEE specification
- It seems numbers are both an object and a primitive but there is little to distinguish at what point one becomes the other
- I get nervous anytime a single definition clause has 4+ "Note that..."s
Let's Look at `Object`
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122747/Screen_Shot_2016-10-16_at_7.05.45_PM.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3122751/Screen_Shot_2016-10-16_at_7.07.31_PM.png)
So...
- An Objects prototype can be the Null value
- The Null value is a primitive, but a Prototype is not
- If a Prototype holds only the Null value, does it have any properties at all?
- If it has no properties, is it then equivalent to Null?
- If Null is a primitive and a Prototype can be Null and a Prototype is a type of Object, does that mean all Primitives are?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/302214/images/3125647/Screen_Shot_2016-10-17_at_9.57.18_AM.png)
I think it might lead here...
I have answers to none of these questions, yet
But I'm working on it!
http://github.com/ybur-yug/numbers-in-js-were-confusing-me
Numbers In JavaScript
By Bobby Grayson
Numbers In JavaScript
- 1,894