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 typeAlthough 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'; // falseThus, 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
booleanfor checking; you can writeif (myVar) {...}directly. - The
typeofoperator 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(); // SyntaxErrorIn 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!