AiTechWorlds
AiTechWorlds
JavaScript is a dynamically typed language. A variable has no fixed type — it holds whatever value you assign to it. Understanding how JavaScript categorizes and converts values is essential for avoiding the category of bugs that trips up beginners and even experienced developers.
JavaScript has 7 primitive types and 1 object type.
Primitives are immutable values. When you work with them, you work with the value directly — not a reference.
// 1. String — text, always in quotes (single, double, or backtick)
const name = "Alice";
const greeting = 'Hello';
const message = `Hi, ${name}`; // template literal — more on this below
// 2. Number — integers and decimals share one type
const age = 30;
const price = 9.99;
const negative = -42;
const scientific = 1.5e6; // 1500000
// 3. BigInt — integers too large for Number (> 2^53 - 1)
const bigNumber = 9007199254740991n; // note the 'n' suffix
// 4. Boolean — only two values
const isActive = true;
const isDeleted = false;
// 5. undefined — a variable declared but not assigned
let score;
console.log(score); // undefined
// 6. null — an intentional absence of value (you set this explicitly)
const selectedUser = null;
// 7. Symbol — a unique, immutable identifier (advanced, used for object keys)
const id = Symbol("id");
Everything that is not a primitive is an object. This includes plain objects, arrays, functions, dates, and regular expressions.
const user = { name: "Alice", age: 30 }; // object
const scores = [98, 87, 92]; // array (a special object)
function greet() {} // function (also a special object)
typeof returns a string describing the type of a value.
typeof "hello" // "string"
typeof 42 // "number"
typeof 9n // "bigint"
typeof true // "boolean"
typeof undefined // "undefined"
typeof Symbol() // "symbol"
typeof {} // "object"
typeof [] // "object" (arrays are objects)
typeof function(){}// "function"
typeof null // "object"
This is a well-known bug in JavaScript that has existed since the language was created in 1995. It cannot be fixed without breaking existing code on the web. null is a primitive — it is not an object. When checking for null, use strict equality:
const value = null;
console.log(value === null); // true — correct way to check for null
console.log(typeof value === "object"); // true — misleading, don't rely on this
JavaScript automatically converts types when operators are used with mismatched types. This is called implicit coercion, and it is the source of JavaScript's most infamous quirks.
+ either adds numbers or concatenates strings. If either operand is a string, both are treated as strings.
"5" + 3 // "53" — 3 is coerced to a string
"5" + true // "5true"
1 + 2 + "3" // "33" — left to right: 1+2=3, then 3+"3"="33"
"3" + 1 + 2 // "312" — left to right: "3"+1="31", then "31"+2="312"
All other arithmetic operators (-, *, /, %) coerce strings to numbers:
"5" - 3 // 2
"5" * 2 // 10
"5" - true // 4 (true coerces to 1)
"5" - false // 5 (false coerces to 0)
"5" - null // 5 (null coerces to 0)
These are real JavaScript expressions you can run in any browser console:
[] + [] // "" — two arrays coerce to empty strings, concatenated
[] + {} // "[object Object]"
{} + [] // 0 — {} is parsed as an empty block, not an object; +[] is 0
true + true // 2
true + false // 1
[] == false // true
null == undefined // true
null == false // false (null only loosely equals undefined)
NaN == NaN // false (NaN is not equal to anything, including itself)
These results exist because of coercion rules, and they are why professional JavaScript relies on strict equality.
== (loose equality) — coerces types before comparing=== (strict equality) — compares value and type, no coercion0 == false // true — false coerces to 0
0 === false // false — different types
"" == false // true
"" === false // false
null == undefined // true
null === undefined // false
1 == "1" // true
1 === "1" // false
Always use === in professional code. The only legitimate use of == is checking for null and undefined simultaneously: value == null catches both.
NaN is a number type value that represents an invalid numeric operation.
typeof NaN // "number" — confusingly, NaN is of type number
"hello" * 2 // NaN
parseInt("abc") // NaN
0 / 0 // NaN
NaN is the only value in JavaScript that is not equal to itself. Use Number.isNaN() to check for it:
NaN === NaN // false
isNaN("hello") // true — misleading: converts to number first, then checks
Number.isNaN("hello") // false — correct: only true if value is actually NaN
Number.isNaN(NaN) // true
Prefer Number.isNaN() over the global isNaN().
When you need to convert types, do it explicitly so the intent is clear.
// To Number
Number("42") // 42
Number("3.14") // 3.14
Number("") // 0
Number("hello") // NaN
Number(true) // 1
Number(false) // 0
Number(null) // 0
Number(undefined) // NaN
parseInt("42px") // 42 — parses leading integer from a string
parseFloat("3.5kg") // 3.5
// To String
String(42) // "42"
String(true) // "true"
String(null) // "null"
String(undefined)// "undefined"
(42).toString() // "42"
// To Boolean
Boolean(0) // false
Boolean("") // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(NaN) // false
Boolean(false) // false
// Everything else is true:
Boolean(1) // true
Boolean("hello") // true
Boolean([]) // true — empty array is truthy!
Boolean({}) // true — empty object is truthy!
In a boolean context (like an if condition), every value in JavaScript is either truthy or falsy.
The 6 falsy values:
false, 0, "", null, undefined, NaN
Every other value is truthy, including "0", [], and {}.
if ("") {
console.log("falsy — this won't run");
}
if ("hello") {
console.log("truthy — this runs"); // "truthy — this runs"
}
if ([]) {
console.log("empty array is truthy — this runs"); // runs
}
This is used in practice to check whether a value exists before using it:
const username = getUserInput(); // might return "" or a name
if (username) {
console.log(`Welcome, ${username}`);
} else {
console.log("Please enter a username");
}
Template literals (backtick strings) allow embedded expressions and multi-line strings without concatenation:
const product = "keyboard";
const price = 79.99;
// Old way — hard to read
const msg1 = "The " + product + " costs $" + price;
// Template literal — clean and readable
const msg2 = `The ${product} costs $${price}`;
console.log(msg2); // "The keyboard costs $79.99"
// Multi-line
const html = `
<div class="card">
<h2>${product}</h2>
<p>$${price}</p>
</div>
`;
Any valid JavaScript expression can go inside ${}:
const a = 10;
const b = 5;
console.log(`${a} + ${b} = ${a + b}`); // "10 + 5 = 15"
console.log(`${a > b ? "greater" : "lesser"}`); // "greater"
typeof null returns "object" — this is a known bug. Use === null to check for null.+ concatenates if any operand is a string; other operators convert to numbers.=== for comparisons. Avoid == except for the value == null pattern.Number.isNaN() not isNaN().false, 0, "", null, undefined, NaN. Everything else is truthy.Get this course's notes on Telegram!
Free cheat sheets, summaries & practice exercises