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...
So the other day I saw something weird
Someone shared this code snipped from V8
Programmers only ever pick arbitrary numbers that are powers of 2
Hmmm
*spelunking begins*
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
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
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
> 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
The Full Number Specification
Per ECMAScript 2016
Some Interesting Points
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`
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?
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,973