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