Built-in Types
JavaScript defines seven built-in types:
null
undefined
boolean
number
string
object
symbol
— added in ES6!
Note: All of these types except object
are called “primitives”.
The typeof
operator inspects the type of the given value, and always returns one of seven string values — surprisingly, there’s not an exact 1-to-1 match with the seven built-in types we just listed.
typeof undefined === "undefined"; // true
typeof true === "boolean"; // true
typeof 42 === "number"; // true
typeof "42" === "string"; // true
typeof { life: 42 } === "object"; // true
// added in ES6!
typeof Symbol() === "symbol"; // true
These six listed types have values of the corresponding type and return a string value of the same name, as shown. Symbol
is a new data type as of ES6, and will be covered in Chapter 3.
As you may have noticed, I excluded null
from the above listing. It’s special — special in the sense that it’s buggy when combined with the typeof
operator:
typeof null === "object"; // true
It would have been nice (and correct!) if it returned "null"
, but this original bug in JS has persisted for nearly two decades, and will likely never be fixed because there’s too much existing web content that relies on its buggy behavior that “fixing” the bug would create more “bugs” and break a lot of web software.
If you want to test for a null
value using its type, you need a compound condition:
var a = null;
(!a && typeof a === "object"); // true
null
is the only primitive value that is “falsy” (aka false-like; see Chapter 4) but that also returns "object"
from the typeof
check.
So what’s the seventh string value that typeof
can return?
typeof function a(){ /* .. */ } === "function"; // true
It’s easy to think that function
would be a top-level built-in type in JS, especially given this behavior of the typeof
operator. However, if you read the spec, you’ll see it’s actually a “subtype” of object. Specifically, a function is referred to as a “callable object” — an object that has an internal [[Call]]
property that allows it to be invoked.
The fact that functions are actually objects is quite useful. Most importantly, they can have properties. For example:
function a(b,c) {
/* .. */
}
The function object has a length
property set to the number of formal parameters it is declared with.
a.length; // 2
Since you declared the function with two formal named parameters (b
and c
), the “length of the function” is 2
.
What about arrays? They’re native to JS, so are they a special type?
typeof [1,2,3] === "object"; // true
Nope, just objects. It’s most appropriate to think of them also as a “subtype” of object (see Chapter 3), in this case with the additional characteristics of being numerically indexed (as opposed to just being string-keyed like plain objects) and maintaining an automatically updated .length
property.