Types of types
Whenever I write anything based on presentations I go back and re-research the things I say in the talk. I do this because I might have been wrong about something I said and I can’t deny anything I put down in writing. The original slide deck for this series has a slide titled Primitive Types. When I began outlining this post I went out and tried to find an authoritative source to confirm what that slide says only to discover several sources that showed my slide to be slightly wrong! The problem was that these sources disagreed with each other!
That list is very interesting because as you saw in the previous post the result of typeof() for a function is ‘function’ (even though a function is really an object):
Just as interestingly, the typeof(null) is ‘object’ (even though null is really a Null):
Therefore, it seems that if I try to apply rigor to my discussion of the type system I will go down the rabbit hole into wonderland and focus on minute details and that is not the goal of these posts! For the purpose of this discussion I’m going to be a little lazy and simply focus on the types as described by the possible return values of typeof.
undefined of type
undefined whose value is undefined. This is illustrated by the following boolean expression (http://jsfiddle.net/DougWare/NAGAr/).
You can test for the value undefined in a function with arguments to determine if the caller supplied an argument (http://jsfiddle.net/DougWare/MXaWB/).
The test for undefined in this example is safe because the existence of a variable named arg within the function’s scope is certain. However, in cases where the existence of a variable with a given name is not guaranteed you should always use typeof (http://jsfiddle.net/DougWare/2D3ds/).
If you test an undeclared variable for any value including undefined a runtime error is the result!
null of type
The Perils of Type Coercion, == Versus ===
Unless you already understood the reason, you were probably wondering why the examples of undefined used === but the example of null used ==. The answer is that === evaluates both the value and the type and is called the identity operator, but ==, the equality operator, attempts to coerce the types before the comparison. Consider this example (http://jsfiddle.net/DougWare/NPre7/).
Coercion in Boolean Expressions
The uninitialized values of the primitive data types evaluate to false when coerced in a Boolean expression, but they don’t all evaluate to true in other cases. The number 1 coerces to true, but other numbers evaluate to false. Boolean expressions that contain null or undefined values always evaluate to false unless you are comparing to null or undefined. Consider this example (http://jsfiddle.net/DougWare/xrGjV/1/).
Pretty weird eh? The key takeaway is that you should not rely on type coercion in your boolean expressions because the rules are bizarre.
Every Rule has an Exception
The one scenario where I think it is generally OK to leverage type coercion is when you need to initialize an argument to a function that wasn’t supplied by the caller. This technique relies on the fact that undefined values in boolean expressions evaluate to false in conjunction with the boolean or operator, | (http://jsfiddle.net/DougWare/uY6MR/1/).
The previous example is still a bit lazy because it doesn’t validate that the argument is a valid type, but in my opinion it is perfectly correct to throw an error if you expect a named argument to be of one type but the caller provides a different type. However, there are still many situations where you might need to cast a value, especially when you need a number from HTML text like the value of an input field. The basic cast functions are:
Perhaps unsurprisingly, these don’t behave quite the same way their implicit coercions do (http://jsfiddle.net/DougWare/7hHjd/).
This post completely ignored objects. I’ll talk about those soon, but that I’ll go back to functions and examine the scary sounding but simple concept of closures.
Author: Doug Ware