JavaScript Core/
Lesson

When AI generates JavaScript, every value it creates has a type, and AI frequently gets type handling wrong. It mixes strings with numbers, forgets null checks, and uses loose equality. Understanding JavaScript's type system is how you catch these bugs before they ship.

The two families: Primitives vs Objects

JavaScript values fall into two categories. Primitives are simple, immutable values, strings, numbers, booleans. Objects are mutable collections that can hold multiple values. AI-generated code constantly moves between them, and knowing the difference is how you spot coercion bugs.

Primitive types (7 total)

Primitives are immutable. When you "change" a string, you're actually creating a new one:

const greeting = "hello";
const shout = greeting.toUpperCase();
console.log(greeting); // "hello" (unchanged!)
console.log(shout);    // "HELLO" (new string)

Here are all seven primitives:

TypeDescriptionExample
stringText data"hello", 'world', ` template | | number | Integers and floats | 42, 3.14, -100 | | boolean | True or false | true, false | | null | Intentional absence of value | null | | undefined | Uninitialized variable | undefined | | symbol | Unique identifier (ES6+) | Symbol('id') | | bigint | Arbitrary precision integers | 9007199254740991n`

Object types

Objects are mutable collections that can hold multiple values:

// Plain object
const user = { name: "Alice", age: 25 };

// Array (special type of object)
const numbers = [1, 2, 3, 4, 5];

// Function (also an object!)
function greet() { return "Hello"; }
02

Working with typeof

The typeof operator tells you what type a value is. But it has some quirks you need to know:

typeof "hello"           // "string"
typeof 42                // "number"
typeof true              // "boolean"
typeof undefined         // "undefined"
typeof Symbol('id')      // "symbol"
typeof 9007199254740991n // "bigint"

// Now the quirks:
typeof null              // "object" (BUG! Should be "null")
typeof []                // "object" (arrays are objects)
typeof {}                // "object"
typeof function(){}      // "function" (special case)
Why is typeof null "object"? This is a bug from the first version of JavaScript (1995) that was never fixed because fixing it would break existing websites. The specification actually says null is its own type, but the implementation returns "object". You'll just have to remember this one.
AI pitfall
AI tools routinely ignore type coercion bugs. They'll compare a form input (string) directly to a number with == instead of ===, or concatenate a string with a number expecting addition. When AI generates code that mixes types, especially around form inputs, API responses, or user data, always check whether it uses === for comparisons and explicit conversion (Number(), String()) before arithmetic.

Checking for arrays

Since typeof [] returns "object", how do you check if something is an array?

const arr = [1, 2, 3];

// Modern way (ES6+)
Array.isArray(arr);      // true
Array.isArray({});       // false

// Old way (don't use this)
arr instanceof Array;    // true, but doesn't work across frames

Checking for null

Since typeof null lies to us, use strict equality:

const value = null;

value === null;          // true
typeof value === "object" && value !== null; // true (but why bother?)
03

Dynamic typing in action

JavaScript is dynamically typed, meaning variables can hold any type and can change types:

let data = "hello";      // string
data = 42;               // number
data = true;             // boolean
data = { name: "Alice" }; // object
data = [1, 2, 3];        // array

This flexibility is powerful but can lead to bugs. TypeScript (which we'll cover later) adds static typing to catch these issues at compile time.

Type coercionWhat is type coercion?JavaScript automatically converting a value from one type to another during an operation, like turning a string into a number for subtraction. gotchas

Because of dynamic typing, JavaScript often converts types automatically:

console.log("5" + 3);     // "53" (string concatenation)
console.log("5" - 3);     // 2 (numeric subtraction)
console.log("5" * 3);     // 15 (numeric multiplication)
console.log("5" == 5);    // true (coerced equality)
console.log("5" === 5);   // false (strict equality)
04

When to use each type

Use CaseTypeExample
User input, messages, IDsstringconst name = "Alice"
Counts, calculations, pricesnumberconst price = 19.99
Flags, conditions, togglesbooleanconst isActive = true
Missing optional datanullconst middleName = null
Uninitialized variablesundefinedlet data;
Unique object keyssymbolconst id = Symbol('userId')
Large integersbigintconst huge = 12345678901234567890n
Complex data structuresobjectconst user = { name: "Alice" }
Ordered collectionsarrayconst items = ["a", "b", "c"]
Practical tip
Use null when you want to explicitly indicate "no value" (like clearing a form field). Use undefined when something hasn't been set yet (like a function parameter that wasn't provided). This distinction helps other developers understand your intent.
05

Type checking in practice

Here's a robust pattern for checking types:

function processValue(value) {
  if (value === null) {
    console.log("Value is null");
  } else if (value === undefined) {
    console.log("Value is undefined");
  } else if (Array.isArray(value)) {
    console.log("Value is an array with " + value.length + " items");
  } else {
    console.log("Value is " + typeof value);
  }
}

processValue(null);           // "Value is null"
processValue(undefined);      // "Value is undefined"
processValue([1, 2, 3]);      // "Value is an array with 3 items"
processValue("hello");        // "Value is string"
06

Quick reference

CheckHowGotcha
Is it a string?typeof x === "string"Works reliably
Is it a number?typeof x === "number"NaN is also a number
Is it null?x === nulltypeof null returns "object"
Is it an array?Array.isArray(x)typeof [] returns "object"
Is it undefined?typeof x === "undefined"Safe even if x is not declared
javascript
// Primitives
const name = "Alice";
const age = 25;
const isStudent = true;
const nothing = null;
let notAssigned;
const uniqueId = Symbol('id');
const hugeNumber = 9007199254740991n;

// Objects
const user = { name: "Alice", age: 25 };
const hobbies = ["coding", "reading", "gaming"];

// Type checking
console.log(typeof name);           // "string"
console.log(typeof age);            // "number"
console.log(typeof isStudent);      // "boolean"
console.log(typeof nothing);        // "object" (quirk!)
console.log(typeof notAssigned);    // "undefined"
console.log(typeof uniqueId);       // "symbol"
console.log(typeof hugeNumber);     // "bigint"
console.log(typeof user);           // "object"
console.log(typeof hobbies);        // "object"

// Better array checking
console.log(Array.isArray(hobbies)); // true
console.log(Array.isArray(user));    // false

// Null checking
console.log(nothing === null);      // true