JavaScript 7 🧬 Automatic type conversion and typeof operator
JavaScript is a dynamically typed language, meaning variables can hold any type of value. Understanding how JavaScript automatically converts types and how to check types with typeof is essential for writing reliable code.
A Quick Look at the Examples
// Automatic type conversion
console.log(1 + '2'); // "12" (number → string)
console.log('10' - '4'); // 6 (strings → numbers)
console.log('10' + 4); // "104" (number → string, concatenated)
console.log(5 * null); // 0 (null → 0)
console.log(5 * true); // 5 (true → 1)
console.log(5 * false); // 0 (false → 0)
// typeof operator
console.log(typeof 42); // "number"
console.log(typeof 'Hello'); // "string"
console.log(typeof ""); // "string"
console.log(typeof true); // "boolean"
let x;
console.log(typeof x); // "undefined"
const obj = { key: 'value' };
console.log(typeof obj); // "object"
function myFunction() {}
console.log(typeof myFunction); // "function"
const str = new String('Hello');
console.log(typeof str); // "object"
a. Automatic Data Type Conversion
JavaScript automatically converts data types between strings, numbers, and booleans. This process is also known as implicit type conversion or type coercion.
The Rules
| Operation | Conversion | Result |
|---|---|---|
+ with string | Number → String | Concatenation |
-, *, /, % | String → Number | Arithmetic |
+ with boolean | Boolean → Number (or String) | Depends on context |
* with null | null → 0 | Number |
* with undefined | undefined → NaN | NaN |
The + Operator — Special Case
The + operator is overloaded: it does addition for numbers and concatenation for strings.
// If ANY operand is a string, + becomes concatenation
console.log(1 + '2'); // "12" (1 → "1", then "1" + "2")
console.log('10' + 4); // "104" (4 → "4", then "10" + "4")
console.log('Hello' + 5); // "Hello5"
console.log(1 + 2); // 3 (both numbers — real addition)
console.log(true + 1); // 2 (true → 1)
The Other Arithmetic Operators
For -, *, /, and %, JavaScript converts everything to numbers.
console.log('10' - '4'); // 6 (both strings → numbers)
console.log('10' * '4'); // 40
console.log('10' / '4'); // 2.5
console.log('10' % '4'); // 2
console.log('abc' - 5); // NaN (cannot convert "abc" to number)
Conversion of null, undefined, and Booleans
| Value | To Number | To String | To Boolean |
|---|---|---|---|
null | 0 | "null" | false |
undefined | NaN | "undefined" | false |
true | 1 | "true" | true |
false | 0 | "false" | false |
"" (empty string) | 0 | "" | false |
"hello" | NaN | "hello" | true |
0 | 0 | "0" | false |
1 | 1 | "1" | true |
console.log(5 * null); // 0 (null → 0)
console.log(5 * true); // 5 (true → 1)
console.log(5 * false); // 0 (false → 0)
console.log(5 * undefined); // NaN (undefined → NaN)
console.log(5 + true); // 6 (true → 1, then 5 + 1)
console.log('5' + true); // "5true" (true → "true")
Truthy and Falsy Values
When converting to boolean, JavaScript uses truthy and falsy values.
Falsy values (convert to false):
false0and-00n(BigInt zero)""(empty string)nullundefinedNaN
Truthy values (everything else, including):
"0"(non-empty string)"false"(non-empty string)[](empty array){}(empty object)function() {}(function)
// Falsy values
if ("") console.log("not reached");
if (0) console.log("not reached");
if (null) console.log("not reached");
if (undefined) console.log("not reached");
if (NaN) console.log("not reached");
// Truthy values
if ("0") console.log("This runs!"); // Non-empty string
if ([]) console.log("This runs!"); // Empty array
if ({}) console.log("This runs!"); // Empty object
if (function() {}) console.log("This runs!"); // Function
Explicit Conversion (Best Practice)
For clarity, use explicit conversion methods:
| Method | Description | Example |
|---|---|---|
Number(value) | Convert to number | Number("10") → 10 |
String(value) | Convert to string | String(42) → "42" |
Boolean(value) | Convert to boolean | Boolean(0) → false |
parseInt(string) | Parse integer | parseInt("10px") → 10 |
parseFloat(string) | Parse float | parseFloat("3.14") → 3.14 |
// Explicit conversion
console.log(Number("10")); // 10
console.log(Number("3.14")); // 3.14
console.log(Number("")); // 0
console.log(Number("abc")); // NaN
console.log(String(42)); // "42"
console.log(String(true)); // "true"
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean("hello")); // true
console.log(parseInt("10px")); // 10
console.log(parseFloat("3.14")); // 3.14
b. The typeof Operator
The typeof operator is used to determine the type of a variable or value. It returns a string indicating the type of the operand.
Useful for: Debugging and ensuring variables are of expected types.
Syntax
typeof value;
typeof(value); // Parentheses are optional
Return Values
| Type | typeof Returns | Example |
|---|---|---|
| Number | "number" | typeof 42 |
| String | "string" | typeof 'Hello' |
| Boolean | "boolean" | typeof true |
| undefined | "undefined" | typeof x (undeclared or unassigned) |
| Null | "object" ⚠️ | typeof null — famous JavaScript quirk! |
| Symbol | "symbol" | typeof Symbol() |
| BigInt | "bigint" | typeof 123n |
| Object | "object" | typeof {} |
| Array | "object" ⚠️ | typeof [] — arrays are objects! |
| Function | "function" | typeof function() {} |
Examples
// Numbers
console.log(typeof 42); // "number"
console.log(typeof 3.14); // "number"
console.log(typeof NaN); // "number" (yes, NaN is a number!)
console.log(typeof Infinity); // "number"
// Strings
console.log(typeof 'Hello'); // "string"
console.log(typeof ""); // "string"
console.log(typeof "42"); // "string"
// Booleans
console.log(typeof true); // "boolean"
console.log(typeof false); // "boolean"
// Undefined
let x;
console.log(typeof x); // "undefined"
console.log(typeof undeclaredVar); // "undefined" (no error!)
// Null — the famous quirk!
console.log(typeof null); // "object" (this is a historical bug)
// Symbols
console.log(typeof Symbol()); // "symbol"
// BigInt
console.log(typeof 123n); // "bigint"
console.log(typeof BigInt(123)); // "bigint"
// Objects
const obj = { key: 'value' };
console.log(typeof obj); // "object"
console.log(typeof {}); // "object"
console.log(typeof []); // "object" (arrays are objects!)
console.log(typeof new Date()); // "object"
console.log(typeof /regex/); // "object"
// Functions
function myFunction() {}
console.log(typeof myFunction); // "function"
console.log(typeof function() {}); // "function"
console.log(typeof console.log); // "function"
// Wrapper objects
const str = new String('Hello');
console.log(typeof str); // "object" (not "string"!)
const num = new Number(42);
console.log(typeof num); // "object"
const bool = new Boolean(true);
console.log(typeof bool); // "object"
The Famous typeof null Quirk
console.log(typeof null); // "object" — this is a bug from 1995!
Why? In the original JavaScript implementation, values were stored as a type tag + value. The type tag for objects was 0, and null was represented as a null pointer (0x00). So typeof null returned "object" — and it’s never been fixed because too much code depends on it.
How to check for null:
const value = null;
console.log(value === null); // true — use strict equality instead
How to Check for Arrays
Since typeof [] returns "object", use Array.isArray():
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray("hello")); // false
Practical Use: Type Checking
function processValue(value) {
if (typeof value === 'string') {
console.log('String:', value.toUpperCase());
} else if (typeof value === 'number') {
console.log('Number:', value * 2);
} else if (typeof value === 'boolean') {
console.log('Boolean:', !value);
} else if (typeof value === 'function') {
console.log('Function:', value());
} else if (value === null) {
console.log('Null value');
} else if (Array.isArray(value)) {
console.log('Array:', value.length, 'items');
} else if (typeof value === 'object') {
console.log('Object:', Object.keys(value));
} else {
console.log('Unknown type');
}
}
processValue("hello"); // String: HELLO
processValue(42); // Number: 84
processValue(true); // Boolean: false
processValue(null); // Null value
processValue([1, 2, 3]); // Array: 3 items
processValue({ a: 1 }); // Object: ["a"]
Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Type Conversion and typeof</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
color: #333;
line-height: 1.6;
}
h1 { color: #007bff; border-bottom: 3px solid #007bff; padding-bottom: 10px; }
h2 { color: #28a745; border-left: 4px solid #28a745; padding-left: 15px; margin-top: 30px; }
.demo-box {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin: 15px 0;
}
pre {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.8;
}
.keyword { color: #569cd6; }
.string { color: #ce9178; }
.number { color: #b5cea8; }
.function { color: #dcdcaa; }
.comment { color: #6a9955; }
.boolean { color: #569cd6; }
#output {
background: #e9ecef;
padding: 15px;
border-radius: 8px;
margin-top: 15px;
min-height: 40px;
font-family: 'Courier New', monospace;
font-size: 0.85rem;
border-left: 4px solid #007bff;
white-space: pre-wrap;
}
table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
th, td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
th { background: #007bff; color: white; }
tr:nth-child(even) { background: #f8f9fa; }
</style>
</head>
<body>
<h1>Type Conversion and typeof</h1>
<div class="demo-box">
<h2>1. Automatic Type Conversion</h2>
<pre>
console.log(<span class="number">1</span> + <span class="string">'2'</span>); <span class="comment">// "12" (number → string)</span>
console.log(<span class="string">'10'</span> - <span class="string">'4'</span>); <span class="comment">// 6 (strings → numbers)</span>
console.log(<span class="string">'10'</span> + <span class="number">4</span>); <span class="comment">// "104" (number → string)</span>
console.log(<span class="number">5</span> * <span class="boolean">null</span>); <span class="comment">// 0 (null → 0)</span>
console.log(<span class="number">5</span> * <span class="boolean">true</span>); <span class="comment">// 5 (true → 1)</span>
console.log(<span class="number">5</span> * <span class="boolean">false</span>); <span class="comment">// 0 (false → 0)</span>
</pre>
</div>
<div class="demo-box">
<h2>2. typeof Operator</h2>
<pre>
console.log(<span class="keyword">typeof</span> <span class="number">42</span>); <span class="comment">// "number"</span>
console.log(<span class="keyword">typeof</span> <span class="string">'Hello'</span>); <span class="comment">// "string"</span>
console.log(<span class="keyword">typeof</span> <span class="string">""</span>); <span class="comment">// "string"</span>
console.log(<span class="keyword">typeof</span> <span class="boolean">true</span>); <span class="comment">// "boolean"</span>
<span class="keyword">let</span> x;
console.log(<span class="keyword">typeof</span> x); <span class="comment">// "undefined"</span>
<span class="keyword">const</span> obj = { key: <span class="string">'value'</span> };
console.log(<span class="keyword">typeof</span> obj); <span class="comment">// "object"</span>
<span class="keyword">function</span> <span class="function">myFunction</span>() {}
console.log(<span class="keyword">typeof</span> myFunction); <span class="comment">// "function"</span>
<span class="keyword">const</span> str = <span class="keyword">new</span> <span class="function">String</span>(<span class="string">'Hello'</span>);
console.log(<span class="keyword">typeof</span> str); <span class="comment">// "object" (wrapper object!)</span>
</pre>
</div>
<div class="demo-box">
<h2>3. The typeof Table</h2>
<table>
<tr>
<th>Value</th>
<th>typeof</th>
</tr>
<tr><td><code>42</code></td><td><code>"number"</code></td></tr>
<tr><td><code>'Hello'</code></td><td><code>"string"</code></td></tr>
<tr><td><code>true</code></td><td><code>"boolean"</code></td></tr>
<tr><td><code>undefined</code></td><td><code>"undefined"</code></td></tr>
<tr><td><code>null</code></td><td><code>"object"</code> ⚠️</td></tr>
<tr><td><code>Symbol()</code></td><td><code>"symbol"</code></td></tr>
<tr><td><code>123n</code></td><td><code>"bigint"</code></td></tr>
<tr><td><code>{}</code></td><td><code>"object"</code></td></tr>
<tr><td><code>[]</code></td><td><code>"object"</code> ⚠️</td></tr>
<tr><td><code>function() {}</code></td><td><code>"function"</code></td></tr>
</table>
</div>
<div class="demo-box">
<h2>4. Live Output — Type Conversions</h2>
<div id="output">Loading...</div>
</div>
<script>
// ============================================
// Type Conversion — Live Demo
// ============================================
let results = [];
results.push('📌 Automatic Type Conversion:\n');
results.push(' 1 + "2" → ' + (1 + '2') + ' (typeof: ' + typeof (1 + '2') + ')');
results.push(' "10" - "4" → ' + ('10' - '4') + ' (typeof: ' + typeof ('10' - '4') + ')');
results.push(' "10" + 4 → ' + ('10' + 4) + ' (typeof: ' + typeof ('10' + 4) + ')');
results.push(' 5 * null → ' + (5 * null) + ' (typeof: ' + typeof (5 * null) + ')');
results.push(' 5 * true → ' + (5 * true) + ' (typeof: ' + typeof (5 * true) + ')');
results.push(' 5 * false → ' + (5 * false) + ' (typeof: ' + typeof (5 * false) + ')');
results.push(' 5 * undefined → ' + (5 * undefined) + ' (typeof: ' + typeof (5 * undefined) + ')');
results.push('');
results.push('📌 typeof Operator:\n');
results.push(' typeof 42 → ' + typeof 42);
results.push(' typeof "Hello" → ' + typeof 'Hello');
results.push(' typeof "" → ' + typeof "");
results.push(' typeof true → ' + typeof true);
results.push(' typeof undefined → ' + typeof undefined);
results.push(' typeof null → ' + typeof null + ' (⚠️ historical quirk!)');
results.push(' typeof Symbol() → ' + typeof Symbol());
results.push(' typeof 123n → ' + typeof 123n);
results.push(' typeof {} → ' + typeof {});
results.push(' typeof [] → ' + typeof []);
results.push(' typeof function(){} → ' + typeof function() {});
results.push(' typeof new String("Hello") → ' + typeof new String("Hello"));
results.push('');
results.push('📌 Explicit Conversion:\n');
results.push(' Number("10") → ' + Number("10") + ' (typeof: ' + typeof Number("10") + ')');
results.push(' Number("3.14") → ' + Number("3.14") + ' (typeof: ' + typeof Number("3.14") + ')');
results.push(' Number("") → ' + Number("") + ' (typeof: ' + typeof Number("") + ')');
results.push(' Number("abc") → ' + Number("abc") + ' (typeof: ' + typeof Number("abc") + ')');
results.push(' String(42) → ' + String(42) + ' (typeof: ' + typeof String(42) + ')');
results.push(' String(true) → ' + String(true) + ' (typeof: ' + typeof String(true) + ')');
results.push(' Boolean(1) → ' + Boolean(1) + ' (typeof: ' + typeof Boolean(1) + ')');
results.push(' Boolean(0) → ' + Boolean(0) + ' (typeof: ' + typeof Boolean(0) + ')');
results.push(' parseInt("10px") → ' + parseInt("10px") + ' (typeof: ' + typeof parseInt("10px") + ')');
results.push(' parseFloat("3.14") → ' + parseFloat("3.14") + ' (typeof: ' + typeof parseFloat("3.14") + ')');
results.push('');
results.push('📌 Array.isArray():\n');
results.push(' Array.isArray([]) → ' + Array.isArray([]));
results.push(' Array.isArray({}) → ' + Array.isArray({}));
results.push(' Array.isArray("hello") → ' + Array.isArray("hello"));
results.push(' Array.isArray([1,2,3]) → ' + Array.isArray([1, 2, 3]));
document.getElementById('output').textContent = results.join('\n');
</script>
</body>
</html>
Quick Reference — Type Conversion
| Operation | Conversion | Result |
|---|---|---|
+ with string | Number → String | Concatenation |
-, *, /, % | String → Number | Arithmetic |
* with null | null → 0 | Number |
* with undefined | undefined → NaN | NaN |
* with true | true → 1 | Number |
* with false | false → 0 | Number |
Quick Reference — typeof
| Value | typeof Returns |
|---|---|
42 | "number" |
'Hello' | "string" |
true | "boolean" |
undefined | "undefined" |
null | "object" ⚠️ |
Symbol() | "symbol" |
123n | "bigint" |
{} | "object" |
[] | "object" ⚠️ |
function() {} | "function" |
Falsy vs Truthy Values
Falsy (→ false) | Truthy (→ true) |
|---|---|
false | Everything else |
0, -0 | "0" (non-empty string) |
0n (BigInt zero) | [] (empty array) |
"" (empty string) | {} (empty object) |
null | function() {} |
undefined | — |
NaN | — |
Explicit Conversion Methods
| Method | Description | Example |
|---|---|---|
Number(value) | Convert to number | Number("10") → 10 |
String(value) | Convert to string | String(42) → "42" |
Boolean(value) | Convert to boolean | Boolean(0) → false |
parseInt(string) | Parse integer | parseInt("10px") → 10 |
parseFloat(string) | Parse float | parseFloat("3.14") → 3.14 |
Array.isArray(value) | Check if array | Array.isArray([]) → true |
Best Practices
✅ Do This:
// Use explicit conversion for clarity
const num = Number("42");
const str = String(42);
// Use strict equality (===) to avoid type coercion
if (value === 42) { }
// Use Array.isArray() for arrays
if (Array.isArray(value)) { }
// Use typeof for type checking
if (typeof value === 'string') { }
// Use null check with ===
if (value === null) { }
❌ Don’t Do This:
// Don't rely on implicit conversion
const result = "10" + 5; // "105" — surprising!
// Don't use == (loose equality) — it coerces types
if (value == 42) { } // "42" == 42 is true!
// Don't use typeof for arrays
if (typeof value === 'object') { } // Arrays also pass!
// Don't rely on typeof null
if (typeof value === 'null') { } // Never true — use === null
// Don't use wrapper objects
const str = new String("Hello"); // typeof is "object", not "string"
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
"10" + 5 | Returns "105" (string) | Use Number("10") + 5 |
typeof null | Returns "object" | Use value === null |
typeof [] | Returns "object" | Use Array.isArray() |
new String("x") | Returns object, not string | Use String("x") |
0 == "" | Returns true | Use === |
NaN === NaN | Returns false | Use Number.isNaN() |
Pro Tip: Always use explicit conversion (Number(), String(), Boolean()) when you need to change types — it makes your code clearer and less error-prone. Use strict equality (===) to avoid surprising type coercion. Remember the famous quirks: typeof null returns "object" (a historical bug), and typeof [] also returns "object" — use Array.isArray() to check for arrays. And always use Number.isNaN() instead of isNaN() for reliable NaN checks!
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!