JavaScript Core Concepts Reference Guide
Variable Declaration: var, let, and const
// var has function scope and hoisting behavior
// let and const have block scope
// var example
function exampleVar() {
console.log(hoisted); // undefined due to hoisting
if (true) {
var hoisted = "I am hoisted";
}
console.log(hoisted); // accessible outside the block
}
// let example with block scope
function exampleLet() {
if (true) {
let blockScoped = "Only available in this block";
const readOnly = "Cannot be reassigned";
// readOnly = "new value"; // TypeError
}
// console.log(blockScoped); // ReferenceError
}
// const must be initialized
const PI = 3.14159;
const CONFIG = { debug: true };
Key characteristics:
var: function-scoped, hoisted, can be redeclaredlet: block-scoped, not hoisted, temporal dead zone, no redeclarationconst: block-scoped, not hoisted, read-only after initialization
Looping Constructs: for...in versus for...of
const user = { name: "Alice", age: 28, role: "developer" };
// for...in iterates over keys (indices)
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
// for...of iterates over values (works with iterables)
const numbers = [10, 20, 30];
for (let num of numbers) {
console.log(num);
}
for...in: returns keys/indexes, suitable for objects and dictionariesfor...of: returns values, works with arrays, strings, maps, sets
Arrow Functions
// Single parameter - parentheses optional
const square = x => x * x;
// Multiple parameters require parentheses
const add = (a, b) => a + b;
// Multi-line function body requires braces and return
const process = (data, config) => {
const result = data.map(item => item * 2);
return result.filter(x => x > config.min);
};
// Returning objects requires parentheses
const createUser = (name, age) => ({ name, age });
Arrow Functions versus Regular Functions
// Regular function - creates its own 'this' context
const counter = {
count: 0,
increment: function() {
this.count++;
},
// Arrow function - inherits 'this' from enclosing scope
reset: () => {
this.count = 0; // 'this' refers to the outer context
}
};
// Arrow functions cannot be used as constructors
// const instance = new ArrowFunction(); // TypeError
// Arrow functions don't have their own arguments object
const showArgs = (...args) => {
console.log(args); // ['a', 'b', 'c']
};
showArgs('a', 'b', 'c');
Differences:
- Syntax: arrow functions use
=>notation - Arrow functions are always anonymous
- Arrow functions cannot be used as constructors
thisbinding differs significantly- Arrow functions lack
argumentsobject andprototype - Arrow functions cannot be used with
new.target
Constructor Functions
function Vehicle(type, wheels) {
this.type = type;
this.wheels = wheels;
// Avoid returning values from constructors
}
const car = new Vehicle('car', 4);
const motorcycle = new Vehicle('motorcycle', 2);
Constructor rules:
- Must be called with
newkeyword - Convention: capitalized function name
- Should not contain return statements (except primitives)
Data Types
// Primitive types (stored in stack)
const num = 42; // number
const text = "Hello"; // string
const flag = true; // boolean
let empty = null; // null
let notDefined; // undefined
// Reference types (stored in heap with stack reference)
const obj = { key: 'value' };
const arr = [1, 2, 3];
const regex = /\d+/;
const today = new Date();
const fn = function() {};
// typeof operator
console.log(typeof num); // "number"
console.log(typeof text); // "string"
console.log(typeof arr); // "object"
console.log(typeof regex); // "object"
Memory Storage: Stack versus Heap
// Primitives: direct stack storage
let a = 100;
let b = a;
b = 200;
console.log(a); // 100 - unchanged
// Objects: stack holds reference, heap holds data
let obj1 = { value: 100 };
let obj2 = obj1;
obj2.value = 200;
console.log(obj1.value); // 200 - both reference same object
JSON Objects
// Creating JSON
const user = {
"id": 101,
"name": "Bob",
"active": true,
"tags": ["admin", "editor"]
};
// Property access
console.log(user.name); // dot notation
console.log(user["id"]); // bracket notation
// Adding properties
user.role = "moderator";
user["email"] = "bob@example.com";
// Removing properties
delete user.active;
delete user["tags"];
// Iterating with for...in
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
// JSON conversion
const jsonString = JSON.stringify(user);
const parsedObject = JSON.parse(jsonString);
Comparision Operators
// Assignment operator
let x = 10;
// Loose equality (type coercion)
console.log(5 == "5"); // true
console.log(true == 1); // true
// Strict equality (no type coercion)
console.log(5 === "5"); // false
console.log(true === 1); // false
// Best practice: use === and !==
Type Conversion
// Implicit conversion - addition
console.log("5" + 3); // "53" (string)
console.log("5" - 3); // 2 (number)
console.log("hello" - 5); // NaN
// Explicit conversion
const strNum = "42.5";
parseInt(strNum); // 42
parseFloat(strNum); // 42.5
Number(strNum); // 42.5
// Number to string
const num = 100;
num.toString(); // "100"
String(num); // "100"
num + ""; // "100"
Ternary Operator
const max = (a, b) => a > b ? a : b;
const grade = score => score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" : "F";
const status = isLoggedIn ? "Welcome back" : "Please log in";
Variable Hoisting
console.log(hoistedVar); // undefined (not an error)
var hoistedVar = "I exist";
// Equivalent to:
var hoistedVar;
console.log(hoistedVar); // undefined
hoistedVar = "I exist";
// let and const are not hoisted in the same way
// console.log(hoistedLet); // ReferenceError
let hoistedLet = "blocked";
Strict Mode
"use strict";
// Must declare variables before use
misdeclared = "error"; // ReferenceError
// Prevents using reserved words
// var let = 5; // SyntaxError
// Functions in strict mode have different this behavior
function strictFunc() {
"use strict";
return this === undefined; // true when called without context
}
BOM and DOM
// BOM - Browser Object Model
window.innerWidth; // viewport width
window.innerHeight; // viewport height
window.location.href; // current URL
navigator.userAgent; // browser info
history.back(); // navigation
// DOM - Document Object Model
document.getElementById("elementId");
document.querySelector(".className");
document.querySelectorAll("div");
Event Handling and Compatibility
// Event object normalization
document.addEventListener('click', function(e) {
const event = e || window.event;
const target = event.target || event.srcElement;
// Keyboard code
const keyCode = event.keyCode || event.which || event.charCode;
// Stop propagation
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
// Prevent default behavior
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
});
// Scroll position
const scrollTop = document.documentElement.scrollTop ||
document.body.scrollTop;
Array Methods
const fruits = ["apple", "banana"];
// Adding elements
fruits.push("orange"); // ["apple", "banana", "orange"] - returns new length
fruits.unshift("mango"); // ["mango", "apple", "banana", "orange"] - returns new length
// Removing elements
const last = fruits.pop(); // removes "orange" - returns removed element
const first = fruits.shift(); // removes "mango" - returns removed element
// Splice (remove/replace/insert)
const colors = ["red", "green", "blue"];
colors.splice(1, 1, "yellow"); // ["red", "yellow", "blue"]
// Slice (extract without modifying)
const numbers = [1, 2, 3, 4, 5];
const subset = numbers.slice(1, 4); // [2, 3, 4]
// Reverse and concatenate
const reversed = numbers.reverse(); // modifies original
const combined = [1, 2].concat([3, 4]); // [1, 2, 3, 4]
// Join and find
const str = numbers.join("-"); // "1-2-3-4-5"
const idx = numbers.indexOf(3); // 2, or -1 if not found
String Methods
const message = "Hello World";
// Character operations
message.charAt(0); // "H"
message.charCodeAt(0); // 72 (ASCII)
String.fromCharCode(72, 101); // "He"
// Search operations
message.indexOf("World"); // 6
message.lastIndexOf("o"); // 7
message.includes("Hello"); // true
message.startsWith("He"); // true
message.endsWith("ld"); // true
// Transform
message.toUpperCase(); // "HELLO WORLD"
message.toLowerCase(); // "hello world"
message.replace("World", "JS"); // "Hello JS"
// Extract and split
message.slice(0, 5); // "Hello"
message.substring(0, 5); // "Hello"
message.split(" "); // ["Hello", "World"]
Math Object
Math.floor(3.7); // 3 - round down
Math.ceil(3.2); // 4 - round up
Math.round(3.5); // 4 - round to nearest
Math.sqrt(16); // 4 - square root
Math.pow(2, 8); // 256 - power
Math.min(1, -2, 3); // -2
Math.max(1, -2, 3); // 3
Math.abs(-15); // 15 - absolute value
Math.random(); // 0 to 0.999...
// Random integer between min and max
const randomInt = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;
Timers
// Interval timer (repeating)
let count = 0;
const intervalId = setInterval(() => {
console.log(`Tick ${++count}`);
if (count >= 5) clearInterval(intervalId);
}, 1000);
// Timeout timer (once)
const timeoutId = setTimeout(() => {
console.log("This runs once after 2 seconds");
}, 2000);
// Cancel timeout
clearTimeout(timeoutId);
DOM Element Selection
// Single element
document.getElementById("uniqueId");
document.querySelector("#id"); // ID
document.querySelector(".class"); // class
document.querySelector("tag"); // tag
// Multiple elements
document.getElementsByTagName("div");
document.getElementsByClassName("menu");
document.getElementsByName("username");
document.querySelectorAll(".item");
DOM Manipulation
// Create elements
const div = document.createElement("div");
div.textContent = "Dynamic content";
div.className = "container";
// Append and insert
document.body.appendChild(div);
parent.insertBefore(newNode, referenceNode);
parent.insertBefore(element, parent.firstChild);
// Remove
div.remove();
DOM Traversal
const parent = document.querySelector(".parent");
// Children
parent.firstElementChild;
parent.lastElementChild;
parent.children; // element nodes only
parent.childNodes; // all nodes including text
// Siblings
element.nextElementSibling;
element.previousElementSibling;
// Parent
element.parentNode;
Browser Engines and Prefixes
/* Vendor prefixes for CSS compatibility */
.element {
-webkit-transform: rotate(45deg); /* Chrome, Safari */
-moz-transform: rotate(45deg); /* Firefox */
-o-transform: rotate(45deg); /* Opera */
-ms-transform: rotate(45deg); /* IE/Edge */
transform: rotate(45deg); /* Standard */
}
| Browser | Engine | Prefix |
|---|---|---|
| Chrome | Blink (formerly WebKit) | -webkit- |
| Safari | WebKit | -webkit- |
| Firefox | Gecko | -moz- |
| Opera | Blink | -o- |
| Edge | Chromium | -ms- |
Array Deduplication
// Method 1: Set
const nums = [1, 2, 2, 3, 3, 3, 4, 5, 5];
const unique1 = [...new Set(nums)];
// Method 2: indexOf
const unique2 = nums.filter((item, index) =>
nums.indexOf(item) === index
);
// Method 3: includes
const unique3 = [];
nums.forEach(item => {
if (!unique3.includes(item)) {
unique3.push(item);
}
});
ES6 Class Syntax
class Animal {
constructor(name, sound) {
this.name = name;
this.sound = sound;
}
speak() {
console.log(`${this.name} says ${this.sound}`);
}
static create(name, sound) {
return new Animal(name, sound);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name, "Woof");
this.breed = breed;
}
}
const dog = new Dog("Rex", "Shepherd");
dog.speak();
Shallow versus Deep Copy
// Shallow copy - shares reference
const original = { nested: { value: 1 } };
const shallow = original;
shallow.nested.value = 99;
console.log(original.nested.value); // 99 - both point to same object
// Deep copy - independent data
const deep = JSON.parse(JSON.stringify(original));
deep.nested.value = 100;
console.log(original.nested.value); // 99 - original unchanged
// Deep copy with spread (shallow for nested objects)
const spreadCopy = { ...original };
Reflow and Repaint
// Repaint only (style change)
element.style.backgroundColor = "blue";
element.style.visibility = "hidden";
// Triggers reflow (layout change)
element.style.width = "200px";
element.style.padding = "20px";
element.className = "large";
// Efficient approach: batch DOM reads and writes
const width = element.offsetWidth; // read
element.style.width = (width * 2) + "px"; // write
Triggers for reflow:
- Element dimension changes (width, hieght, margin, padding)
- Adding/removing elements
- Browser window resize
- Reading offsetWidth, offsetHeight properties
Object-Oriented Programming
// Encapsulation
const calculator = {
result: 0,
add(value) { this.result += value; return this; },
subtract(value) { this.result -= value; return this; },
getResult() { return this.result; }
};
// Inheritance via prototype
function Mammal(name) {
this.name = name;
}
Mammal.prototype.breathe = function() {
return `${this.name} is breathing`;
};
function Dog(name, breed) {
Mammal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Mammal.prototype);
Dog.prototype.constructor = Dog;
AJAX Fundamentals
// XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/data", true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
};
// GET parameters in URL
xhr.open("GET", "/api/search?q=term&limit=10", true);
// POST parameters in body
xhr.open("POST", "/api/submit", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify({ name: "value" }));
ReadyState values:
- 0: request not initialized
- 1: server connection established
- 2: request received
- 3: processing request
- 4: request finished, response ready
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | OK - request succeeded |
| 201 | Created - resource created |
| 204 | No Content - success with no body |
| 301 | Moved Permanently - redirect |
| 304 | Not Modified - use cached |
| 400 | Bad Request - malformed syntax |
| 401 | Unauthorized - authentication needed |
| 403 | Forbidden - access denied |
| 404 | Not Found - resource doesn't exist |
| 408 | Request Timeout |
| 500 | Internal Server Error |
| 502 | Bad Gateway |
| 503 | Service Unavailable |
| 504 | Gateway Timeout |
Promise Patterns
// Basic promise
const fetchData = () => new Promise((resolve, reject) => {
setTimeout(() => resolve("data"), 1000);
});
// Chaining
fetchData()
.then(data => data.toUpperCase())
.then(upper => console.log(upper))
.catch(err => console.error(err));
// Parallel execution
Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/settings').then(r => r.json())
]).then(([users, settings]) => {
// Both complete
});
// Race (first to resolve wins)
Promise.race([
fetch('/fast-server/data').then(r => r.json()),
fetch('/slow-server/data').then(r => r.json())
]).then(data => console.log(data));
Asynchronous Programming
// Synchronous execution
console.log("1");
console.log("2");
console.log("3");
// Asynchronous patterns
console.log("A");
setTimeout(() => console.log("B"), 0);
console.log("C");
// Output: A, C, B (setTimeout always runs after sync code)
// Callback pattern
function asyncTask(callback) {
setTimeout(() => callback("complete"), 500);
}
// Promise pattern
function asyncTask() {
return new Promise(resolve => {
setTimeout(() => resolve("complete"), 500);
});
}
Async sources:
- Timers (setTimeout, setInterval)
- Event handlers
- Network requests
- Animations
Cross-Origin Requests
// CORS (Server-side)
// Add header: Access-Control-Allow-Origin: *
// JSONP (legacy, limited)
// Client defines callback
function handleResponse(data) {
console.log(data);
}
// Server returns: handleResponse({ "key": "value" })
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);
Note: JSONP is not true AJAX, uses script tags instead of XMLHttpRequest.
Closures
// Closure example
function counter() {
let count = 0;
return function() {
return ++count;
};
}
const increment = counter();
console.log(increment()); // 1
console.log(increment()); // 2
console.log(increment()); // 3
// Factory pattern
function multiplier(factor) {
return number => number * factor;
}
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
this Binding
// In event handler - refers to the element
button.addEventListener('click', function() {
console.log(this); // the button element
});
// In regular function - refers to calling object
const obj = {
name: "Test",
method: function() {
console.log(this.name); // "Test"
}
};
// In constructor - refers to new instance
function User(name) {
this.name = name;
}
const user = new User("Alice");
// In arrow function - inherits from enclosing scope
const arrow = () => console.log(this); // refers to outer 'this'
apply, call, and bind
const person = { name: "John", age: 30 };
function introduce(greeting, punct) {
console.log(`${greeting}, I'm ${this.name}${punct}`);
}
// call - invoke immediately with arguments
introduce.call(person, "Hello", "!");
// apply - invoke immediately with array
introduce.apply(person, ["Hi", "..."]);
// bind - create new function with bound context
const boundIntro = introduce.bind(person);
boundIntro("Hey", ".");
// Partially applied arguments
const greetJohn = introduce.bind(person, "Greetings");
greetJohn("!");
Prototype Chain
function Parent() {
this.parentProperty = true;
}
Parent.prototype.parentMethod = function() {
return "from parent";
};
function Child() {
Parent.call(this);
this.childProperty = true;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
// Access hierarchy:
// instance -> Child.prototype -> Parent.prototype -> Object.prototype
const instance = new Child();
console.log(instance.parentProperty); // own property
console.log(instance.parentMethod()); // inherited method
typeof versus instanceof
// typeof for primitives
typeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object" (historical bug)
typeof {}; // "object"
typeof []; // "object"
typeof function() {}; // "function"
// instanceof for object types
[] instanceof Array; // true
{} instanceof Object; // true
new Date() instanceof Date; // true
"string" instanceof String; // false (primitive)
Client-Side Storage
// Session storage (tab lifecycle)
sessionStorage.setItem("tempData", "value");
sessionStorage.getItem("tempData");
sessionStorage.removeItem("tempData");
// Local storage (persists indefinitely)
localStorage.setItem("user", JSON.stringify({ name: "Alice" }));
const userData = JSON.parse(localStorage.getItem("user"));
localStorage.clear();
// Cookie management
document.cookie = "sessionId=abc123; path=/; max-age=3600";
// Cannot set multiple cookies in one statement
// Use encodeURIComponent for special characters
Storage comparison:
- Cookies: 4KB, sent with every request
- sessionStorage: 4-5MB, per tab
- localStorage: 4-5MB, persists until cleared
Lazy Loading Images
// Using IntersectionObserver (modern)
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove("lazy");
obs.unobserve(img);
}
});
});
document.querySelectorAll("img.lazy").forEach(img => {
observer.observe(img);
});
// HTML pattern:
// <img class="lazy" data-src="real-image.jpg" src="placeholder.jpg" alt="">