Appearance
Standard Objects
In the world of JavaScript, everything is an object.
However, some objects are a bit different from others. To distinguish between object types, we use the typeof
operator, which always returns a string:
javascript
typeof 123; // 'number'
typeof 123n; // 'bigint'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'
You can see that number
, bigint
, string
, boolean
, function
, and undefined
differ from other types. Note that the type of null
is object
, and the type of Array
is also object
. Thus, typeof
cannot distinguish between null
, Array
, and the usual object {}
.
Wrapper Objects
In addition to these types, JavaScript also provides wrapper objects. If you’re familiar with Java, you know the ambiguous relationship between int
and Integer
.
number
, boolean
, and string
all have corresponding wrapper objects. In JavaScript, strings distinguish between string
types and their wrapper types. Wrapper objects are created using new
:
javascript
let n = new Number(123); // Creates a new wrapper type
let b = new Boolean(true); // Creates a new wrapper type
let s = new String('str'); // Creates a new wrapper type
Although wrapper objects appear identical to the original values, their type has changed to object
. Therefore, comparing wrapper objects and primitive values using ===
will return false
:
javascript
typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false
Thus, avoid using wrapper objects, especially for string
types!
What happens if you use Number
, Boolean
, and String
without new
?
In this case, Number()
, Boolean()
, and String()
are treated as regular functions, converting any type of data to number
, boolean
, and string
types (note that these are not their wrapper types):
javascript
let n = Number('123'); // 123, equivalent to parseInt() or parseFloat()
typeof n; // 'number'
let b = Boolean('true'); // true
typeof b; // 'boolean'
let b2 = Boolean('false'); // true! The string 'false' converts to true because it is a non-empty string!
let b3 = Boolean(''); // false
let s = String(123.45); // '123.45'
typeof s; // 'string'
Is your head spinning yet? This is the unique hypnotic charm of JavaScript!
Summary
Here are a few rules to follow:
- Do not use
new Number()
,new Boolean()
, ornew String()
to create wrapper objects. - Use
parseInt()
orparseFloat()
to convert any type tonumber
. - Use
String()
to convert any type tostring
, or call an object'stoString()
method directly. - Typically, you don’t need to convert any type to
boolean
for checking; you can writeif (myVar) {...}
directly. - The
typeof
operator can identifynumber
,boolean
,string
,function
, andundefined
. - To check for
Array
, useArray.isArray(arr)
. - For
null
, usemyVar === null
. - To check if a global variable exists, use
typeof window.myVar === 'undefined'
. - To check if a variable exists inside a function, use
typeof myVar === 'undefined'
.
Finally, you may note that every object has a toString()
method, but null
and undefined
do not! This is indeed the case; these two special values are exceptions, although null
disguises itself as an object type.
More observant readers will point out that calling toString()
on a number can throw a SyntaxError
:
javascript
123.toString(); // SyntaxError
In such cases, handle it specially:
javascript
123..toString(); // '123', note the two dots!
(123).toString(); // '123'
Don't ask why; that's just the fun of JavaScript coding!