Weird world of JS Types
Types:
- Numbers 1, 2, 3, 1.28, Nan, Infinity (primitive)
- Strings 'xyz' (primitive)
- Boolean true, false (primitive)
- Objects {course: 'CIS 197', title: 'JavaScript'}
- Array [1, 2, 'hi', 'there']
How to determine types in js?
typeof(someVariable)
Q: What will this return A: Object typeof([]) // object
How do we actually check for arrays?
Array.isArray(arr)
Array.isArray([]) // true Array.isArray({}) // false
Some other operations
For any type: + is addition : way it works is to cast both sides of the addition to their primitive values. For objects, this is the equivalent of calling toString
For any type, there exists a .toString() function that will give a string representation of the object
[].toString() // '' [1].toString() // '1' [1,2].toString() // '1,2'
var obj = {} obj.toString() // '[object Object]'
Why not just do {}.toString()?
If {} is on its own and not being assigned to a variable OR it is not being added to anything as the right arg, it is assumed it is creating a block. Blocks to not have a .toString() property
Also some other things
Array(x) creates an array of length x with empty elements
someVariableContainingAnArray.join("string") will concat elements of an array together with strings
Now for the weird stuff
[] + [] = ''
[] + {} = '[object Object]'
{} + [] = 0
{} + {} = NaN
Array(16).join("wat" - 1) + ' Batman!'= NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!
Why does this happen?
For [] + [] recall + casts args to their prim values. What is the prim value of []? ''
'' + '' => '' done
For [] + {} recall + casts args to their prim values. What is the prim value of [] and {}? '' and '[object Object]' respectively
'' + '[object Object]' = '[object Object]'
For {} + [] this is a bit weird. {} creates a block and is useless to us. So we can essentially reconsider this to be + []. This is a unary addition and works differently from normal addition. In unary addition, we not only cast the right arg to its primitive, but we also attempt to cast that primitive value to a number.
{} + [] = + [] = ToNumber(ToPrimitive([])) = ToNumber('') = 0
// side fact '' = 0
For {} + {} we use a similar thought process. {} creates a block and is useless to us. This is essentially a + {} operation. So
{} + {} = + {} = ToNumber(ToPrimitive({})) = ToNumber('[object Object]') = NaN
Array(16).join("wat" - 1) + ' Batman'
Array(16) creates an array of 16 empty elements. Let's pay attention to the join operation. Per the JS spec, - will convert both sides of the argument to numbers. If one or both of of the resultant numbers is NaN then the result is NaN.
"wat" - 1 = ToNumber("wat") - ToNumber(1) = NaN - 1 = NaN
Array(16).join(NaN) + ' Batman' = 'NaN(x16) Batman'