Asher Cohen
Back to posts

JavaScript Basics: Primitives, Types, Functions, and Scope

Complete guide to JavaScript fundamentals — primitives, type coercion, equality, functions, scope, hoisting, prototypes, and classes

Introduction

Every JavaScript developer needs a solid grasp of the fundamentals. Understanding primitives, type coercion, scope, and prototypes prevents the most common bugs and unlocks the language's full potential.

Primitives

JavaScript has 7 primitive types:

// Primitives (immutable, compared by value)
const str = 'hello';        // string
const num = 42;             // number
const big = 123n;           // bigint
const bool = true;          // boolean
const undef = undefined;    // undefined
const nul = null;           // null
const sym = Symbol('id');   // symbol

// Check types
typeof 'hello';    // 'string'
typeof 42;         // 'number'
typeof true;       // 'boolean'
typeof undefined;  // 'undefined'
typeof null;       // 'object' (historical bug!)
typeof Symbol();   // 'symbol'
typeof 123n;       // 'bigint'

Compound Types (Objects)

Objects are collections of key-value pairs:

// Object literal
const user = { name: 'Alice', age: 30 };

// Array (special object)
const items = [1, 2, 3];

// Function (callable object)
function greet() { return 'Hello'; }

// Access properties
user.name;        // 'Alice'
user['name'];     // 'Alice'

// Add/remove properties
user.city = 'Paris';
delete user.age;

Type Coercion

JavaScript automatically converts types in certain contexts:

// String coercion
'5' + 3;      // '53' (number → string)
'5' - 3;      // 2    (string → number)
'5' * '3';    // 15   (both → number)

// Boolean coercion
// Falsy values: false, 0, '', null, undefined, NaN
// Truthy: everything else

Boolean('');      // false
Boolean('hello'); // true
Boolean(0);       // false
Boolean(42);      // true

// Explicit conversion
String(42);       // '42'
Number('42');     // 42
Boolean(1);       // true

Equality

// == (loose equality — coerces types)
5 == '5';         // true
0 == false;       // true
null == undefined; // true

// === (strict equality — no coercion, preferred)
5 === '5';        // false
0 === false;      // false
null === undefined; // false

// Object comparison (by reference)
{} === {};              // false
const obj = {};
const ref = obj;
obj === ref;            // true

// NaN is never equal to anything
NaN === NaN;            // false
Number.isNaN(NaN);      // true

Functions

// Function declaration (hoisted)
function add(a, b) {
  return a + b;
}

// Function expression (not hoisted)
const subtract = function(a, b) {
  return a - b;
};

// Arrow function (no own this, no arguments)
const multiply = (a, b) => a * b;

// Default parameters
function greet(name = 'Guest') {
  return `Hello, ${name}`;
}

// Higher-order functions
function withLogging(fn) {
  return (...args) => {
    console.log('Called with:', args);
    return fn(...args);
  };
}

Variables, Scope, and Hoisting

Variable Declarations

// var — function-scoped, hoisted, can redeclare
var x = 1;

// let — block-scoped, not hoisted (TDZ), can't redeclare
let y = 2;

// const — block-scoped, can't reassign
const z = 3;

Scope

// Global scope
const global = 'visible everywhere';

function outer() {
  // Function scope
  const outerVar = 'in outer';
  
  if (true) {
    // Block scope (let/const only)
    const blockVar = 'in block';
    let blockLet = 'also in block';
    var functionScoped = 'in function'; // var ignores blocks!
  }
  
  console.log(functionScoped); // 'in function'
  // console.log(blockVar);    // ReferenceError
}

Hoisting

// Function declarations are hoisted
sayHello(); // Works!
function sayHello() { console.log('Hello'); }

// var is hoisted (but value is undefined)
console.log(x); // undefined
var x = 5;

// let/const are NOT hoisted (Temporal Dead Zone)
// console.log(y); // ReferenceError
let y = 5;

Prototypes and Inheritance

Every JavaScript object has a prototype:

// Prototype chain
const arr = [1, 2, 3];
arr.push(4); // push() comes from Array.prototype

// Custom prototype
const animal = {
  speak() { return '...'; }
};

const dog = Object.create(animal);
dog.speak(); // '...' (inherited from animal)

// Constructor function
function User(name) {
  this.name = name;
}

User.prototype.greet = function() {
  return `Hi, I'm ${this.name}`;
};

const alice = new User('Alice');
alice.greet(); // "Hi, I'm Alice"

Classes

ES6 classes are syntactic sugar over prototypes:

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
  
  speak() {
    return `${this.name} barks`;
  }
  
  static create(name) {
    return new Dog(name, 'unknown');
  }
}

const rex = new Dog('Rex', 'German Shepherd');
console.log(rex.speak()); // 'Rex barks'

Conditional Branching

// if/else
if (score >= 90) {
  grade = 'A';
} else if (score >= 80) {
  grade = 'B';
} else {
  grade = 'C';
}

// Ternary
const access = age >= 18 ? 'granted' : 'denied';

// Switch
switch (color) {
  case 'red':
    hex = '#FF0000';
    break;
  case 'green':
    hex = '#00FF00';
    break;
  default:
    hex = '#000000';
}

// Logical operators
const name = userInput || 'Guest';     // Default value
const canAccess = isAdmin && isActive; // Both required
const displayName = user?.name ?? 'Anonymous'; // Nullish coalescing

Date and Time

const now = new Date();
now.getFullYear();    // 2024
now.getMonth();       // 0-11 (January = 0!)
now.getDate();        // 1-31
now.getDay();         // 0-6 (Sunday = 0)

// Formatting
now.toISOString();    // '2024-01-01T00:00:00.000Z'
now.toLocaleDateString('en-US'); // '1/1/2024'

// Intl for proper formatting
new Intl.DateTimeFormat('fr-FR', {
  dateStyle: 'full'
}).format(now); // 'lundi 1 janvier 2024'

Conclusion

These fundamentals are the building blocks of every JavaScript application:

  • Primitives vs Objects — Know what you're working with
  • Type coercion — Understand implicit conversions
  • Strict equality — Always use ===
  • Scope and hoisting — Know where variables live
  • Prototypes — Understand inheritance
  • Classes — Modern syntax for OOP

Master these basics and you'll avoid the most common JavaScript pitfalls.

#javascript #basics #fundamentals #types #functions #web-development