javascript-fundamentals

JavaScript Fundamentals

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "javascript-fundamentals" with this command: npx skills add manutej/luxor-claude-marketplace/manutej-luxor-claude-marketplace-javascript-fundamentals

JavaScript Fundamentals

A comprehensive guide to core JavaScript concepts, modern ES6+ features, asynchronous programming patterns, and industry best practices for building robust applications.

When to Use This Skill

This skill is essential when:

  • Writing JavaScript Code: Building web applications, Node.js backends, or any JavaScript-based project

  • Code Reviews: Evaluating code quality, identifying anti-patterns, suggesting improvements

  • Teaching/Mentoring: Explaining JavaScript concepts, debugging issues, pair programming

  • Refactoring Legacy Code: Modernizing codebases with ES6+ features and better patterns

  • Architecture Design: Choosing appropriate patterns and structures for your application

  • Performance Optimization: Understanding memory management, event loops, and efficient patterns

  • Debugging: Tracing execution flow, understanding scope chains, and async behavior

  • Interview Preparation: Mastering fundamental concepts tested in technical interviews

Core Concepts

Variables and Scope

JavaScript has three ways to declare variables, each with different scoping rules:

var: Function-scoped, hoisted, can be redeclared

function varExample() { var x = 1; if (true) { var x = 2; // Same variable! console.log(x); // 2 } console.log(x); // 2 }

let: Block-scoped, not hoisted to usable state, cannot be redeclared

function letExample() { let x = 1; if (true) { let x = 2; // Different variable console.log(x); // 2 } console.log(x); // 1 }

const: Block-scoped, must be initialized, reference cannot be reassigned

const PI = 3.14159; // PI = 3; // Error: Assignment to constant variable

const user = { name: 'John' }; user.name = 'Jane'; // OK - modifying object properties // user = {}; // Error - reassigning reference

Best Practice: Use const by default, let when reassignment is needed, avoid var .

Data Types

JavaScript has 7 primitive types and objects:

Primitives:

  • String : Text data

  • Number : Integers and floating-point numbers

  • BigInt : Arbitrary precision integers

  • Boolean : true/false

  • undefined : Uninitialized variable

  • null : Intentional absence of value

  • Symbol : Unique identifiers

Objects: Collections of key-value pairs, including arrays, functions, dates, etc.

// Type checking typeof "hello" // "string" typeof 42 // "number" typeof true // "boolean" typeof undefined // "undefined" typeof null // "object" (historical bug!) typeof {} // "object" typeof [] // "object" typeof function(){} // "function"

// Better array checking Array.isArray([]) // true Array.isArray({}) // false

// Null checking value === null // true only for null value == null // true for null AND undefined

Functions

Functions are first-class citizens in JavaScript - they can be assigned to variables, passed as arguments, and returned from other functions.

Function Declaration:

function greet(name) { return Hello, ${name}!; }

Function Expression:

const greet = function(name) { return Hello, ${name}!; };

Arrow Function (ES6+):

const greet = (name) => Hello, ${name}!;

// Multiple parameters const add = (a, b) => a + b;

// Single parameter (parentheses optional) const double = x => x * 2;

// Multiple statements (need braces and explicit return) const complexFunction = (x, y) => { const result = x + y; return result * 2; };

Key Differences:

  • Arrow functions don't have their own this binding

  • Arrow functions cannot be used as constructors

  • Arrow functions don't have arguments object

  • Function declarations are hoisted, expressions are not

Objects and Arrays

Object Creation:

// Object literal const person = { name: 'John', age: 30, greet() { return Hello, I'm ${this.name}; } };

// Accessing properties person.name // Dot notation person['name'] // Bracket notation (dynamic keys)

// Adding/modifying properties person.email = 'john@example.com'; person.age = 31;

// Deleting properties delete person.email;

Array Methods:

const numbers = [1, 2, 3, 4, 5];

// Transformation numbers.map(n => n * 2) // [2, 4, 6, 8, 10] numbers.filter(n => n > 2) // [3, 4, 5] numbers.reduce((sum, n) => sum + n, 0) // 15

// Iteration numbers.forEach(n => console.log(n));

// Search numbers.find(n => n > 3) // 4 numbers.findIndex(n => n > 3) // 3 numbers.includes(3) // true

// Mutation (modify original) numbers.push(6) // Add to end numbers.pop() // Remove from end numbers.unshift(0) // Add to start numbers.shift() // Remove from start numbers.splice(2, 1) // Remove 1 item at index 2

// Non-mutating numbers.slice(1, 3) // [2, 3] numbers.concat([6, 7]) // [1, 2, 3, 4, 5, 6, 7] [...numbers, 6, 7] // Spread operator

Closures

A closure is a function that has access to variables in its outer (enclosing) lexical scope, even after the outer function has returned.

function createCounter() { let count = 0; // Private variable

return { increment() { return ++count; }, decrement() { return --count; }, getCount() { return count; } }; }

const counter = createCounter(); console.log(counter.increment()); // 1 console.log(counter.increment()); // 2 console.log(counter.getCount()); // 2 // count is not directly accessible

Use Cases:

  • Data privacy/encapsulation

  • Factory functions

  • Event handlers

  • Callbacks maintaining state

  • Module pattern implementation

Prototypes and Inheritance

JavaScript uses prototypal inheritance. Every object has an internal [[Prototype]] link to another object.

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

// Add method to prototype Animal.prototype.speak = function() { return ${this.name} makes a sound; };

const dog = new Animal('Dog'); console.log(dog.speak()); // "Dog makes a sound"

// Inheritance function Dog(name, breed) { Animal.call(this, name); // Call parent constructor this.breed = breed; }

// Set up prototype chain Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog;

Dog.prototype.bark = function() { return ${this.name} barks!; };

const myDog = new Dog('Buddy', 'Golden Retriever'); console.log(myDog.speak()); // "Buddy makes a sound" (inherited) console.log(myDog.bark()); // "Buddy barks!" (own method)

Classes (ES6+)

Classes provide syntactic sugar over prototypal inheritance:

class Animal { constructor(name) { this.name = name; }

speak() { return ${this.name} makes a sound; }

// Static method static create(name) { return new Animal(name); } }

class Dog extends Animal { constructor(name, breed) { super(name); // Call parent constructor this.breed = breed; }

speak() { return ${super.speak()} - Woof!; }

// Getter get info() { return ${this.name} is a ${this.breed}; }

// Setter set nickname(value) { this._nickname = value; } }

const myDog = new Dog('Buddy', 'Golden Retriever'); console.log(myDog.speak()); // "Buddy makes a sound - Woof!" console.log(myDog.info); // "Buddy is a Golden Retriever" myDog.nickname = 'Bud';

Modern JavaScript (ES6+)

Destructuring

Extract values from arrays or properties from objects:

// Array destructuring const [first, second, ...rest] = [1, 2, 3, 4, 5]; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4, 5]

// Object destructuring const user = { name: 'John', age: 30, city: 'NYC' }; const { name, age } = user; console.log(name); // "John"

// Renaming const { name: userName, age: userAge } = user;

// Default values const { country = 'USA' } = user;

// Nested destructuring const data = { user: { name: 'John', address: { city: 'NYC' } } }; const { user: { address: { city } } } = data;

// Function parameters function greet({ name, age = 0 }) { return ${name} is ${age} years old; } greet({ name: 'John', age: 30 }); // "John is 30 years old"

Spread and Rest Operators

Spread (... ) expands elements:

// Arrays const arr1 = [1, 2, 3]; const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5] const combined = [...arr1, ...arr2];

// Objects const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }

// Function arguments Math.max(...arr1); // 3

// Shallow copy const copy = [...arr1]; const objCopy = { ...obj1 };

Rest (... ) collects elements:

// Function parameters function sum(...numbers) { return numbers.reduce((total, n) => total + n, 0); } sum(1, 2, 3, 4); // 10

// With other parameters function multiply(multiplier, ...numbers) { return numbers.map(n => n * multiplier); } multiply(2, 1, 2, 3); // [2, 4, 6]

Template Literals

Multi-line strings and string interpolation:

const name = 'John'; const age = 30;

// String interpolation const greeting = Hello, ${name}!;

// Expressions const message = In 5 years, you'll be ${age + 5};

// Multi-line const multiline = This is a multi-line string;

// Tagged templates function highlight(strings, ...values) { return strings.reduce((result, str, i) => { return result + str + (values[i] ? <mark>${values[i]}</mark> : ''); }, ''); }

const html = highlightHello, ${name}! You are ${age} years old.; // "Hello, <mark>John</mark>! You are <mark>30</mark> years old."

Optional Chaining and Nullish Coalescing

Optional Chaining (?. ): Safely access nested properties:

const user = { name: 'John', address: { city: 'NYC' } };

// Without optional chaining const city = user && user.address && user.address.city;

// With optional chaining const city = user?.address?.city; // "NYC" const zip = user?.address?.zip; // undefined (no error!)

// With methods user.getName?.(); // Only calls if method exists

// With arrays const firstItem = arr?.[0];

Nullish Coalescing (?? ): Default values for null/undefined:

// || returns right side for ANY falsy value const value1 = 0 || 'default'; // "default" const value2 = '' || 'default'; // "default" const value3 = false || 'default'; // "default"

// ?? only for null/undefined const value4 = 0 ?? 'default'; // 0 const value5 = '' ?? 'default'; // "" const value6 = false ?? 'default'; // false const value7 = null ?? 'default'; // "default" const value8 = undefined ?? 'default'; // "default"

Modules

Exporting:

// Named exports export const PI = 3.14159; export function add(a, b) { return a + b; } export class Calculator { // ... }

// Export multiple const multiply = (a, b) => a * b; const divide = (a, b) => a / b; export { multiply, divide };

// Default export (one per file) export default class App { // ... }

// Or class App { } export default App;

Importing:

// Named imports import { PI, add } from './math.js'; import { multiply as mult } from './math.js'; // Rename

// Default import import App from './App.js';

// Mix default and named import App, { PI, add } from './App.js';

// Import all import * as Math from './math.js'; Math.PI; Math.add(1, 2);

// Import for side effects only import './polyfills.js';

Asynchronous Patterns

The Event Loop

JavaScript is single-threaded but handles async operations through the event loop:

  • Call Stack: Executes synchronous code

  • Web APIs: Browser/Node APIs (setTimeout, fetch, etc.)

  • Callback Queue: Completed async operations wait here

  • Event Loop: Moves callbacks from queue to stack when stack is empty

console.log('1');

setTimeout(() => { console.log('2'); }, 0);

Promise.resolve().then(() => { console.log('3'); });

console.log('4');

// Output: 1, 4, 3, 2 // Microtasks (Promises) have priority over macrotasks (setTimeout)

Callbacks

Traditional async pattern (can lead to "callback hell"):

function fetchUser(userId, callback) { setTimeout(() => { callback(null, { id: userId, name: 'John' }); }, 1000); }

function fetchPosts(userId, callback) { setTimeout(() => { callback(null, [{ id: 1, title: 'Post 1' }]); }, 1000); }

// Callback hell fetchUser(1, (error, user) => { if (error) { console.error(error); return; }

fetchPosts(user.id, (error, posts) => { if (error) { console.error(error); return; }

console.log(user, posts);

}); });

Promises

Promises represent eventual completion (or failure) of an async operation:

// Creating a promise const promise = new Promise((resolve, reject) => { setTimeout(() => { const success = true; if (success) { resolve('Success!'); } else { reject(new Error('Failed!')); } }, 1000); });

// Using a promise promise .then(result => { console.log(result); // "Success!" return result.toUpperCase(); }) .then(upperResult => { console.log(upperResult); // "SUCCESS!" }) .catch(error => { console.error(error); }) .finally(() => { console.log('Cleanup'); });

// Promise utilities Promise.all([promise1, promise2, promise3]) .then(results => { // All resolved: [result1, result2, result3] });

Promise.race([promise1, promise2]) .then(result => { // First to resolve });

Promise.allSettled([promise1, promise2]) .then(results => { // All completed (resolved or rejected) // [{ status: 'fulfilled', value: ... }, { status: 'rejected', reason: ... }] });

Promise.any([promise1, promise2]) .then(result => { // First to fulfill (resolve) });

Async/Await

Modern syntax for handling promises (ES2017+):

async function fetchUserData(userId) { try { const user = await fetchUser(userId); const posts = await fetchPosts(user.id); const comments = await fetchComments(posts[0].id);

return { user, posts, comments };

} catch (error) { console.error('Error:', error); throw error; } }

// Using the async function fetchUserData(1) .then(data => console.log(data)) .catch(error => console.error(error));

// Parallel execution async function fetchAllData() { const [users, posts, comments] = await Promise.all([ fetchUsers(), fetchPosts(), fetchComments() ]);

return { users, posts, comments }; }

// Sequential vs Parallel async function sequential() { const result1 = await operation1(); // Wait const result2 = await operation2(); // Then wait return [result1, result2]; }

async function parallel() { const [result1, result2] = await Promise.all([ operation1(), // Start both operation2() // simultaneously ]); return [result1, result2]; }

Error Handling in Async Code

// Try-catch with async/await async function robustFetch(url) { try { const response = await fetch(url);

if (!response.ok) {
  throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();
return data;

} catch (error) { if (error.name === 'TypeError') { console.error('Network error:', error); } else { console.error('Error:', error); } throw error; // Re-throw or handle } }

// Promise catch fetchData() .then(data => processData(data)) .catch(error => { // Catches errors from fetchData AND processData console.error(error); });

// Global error handlers window.addEventListener('unhandledrejection', event => { console.error('Unhandled promise rejection:', event.reason); event.preventDefault(); });

Common Patterns

Module Pattern

Encapsulate private data and expose public API:

const Calculator = (function() { // Private variables let history = [];

// Private function function log(operation) { history.push(operation); }

// Public API return { add(a, b) { const result = a + b; log(${a} + ${b} = ${result}); return result; },

subtract(a, b) {
  const result = a - b;
  log(`${a} - ${b} = ${result}`);
  return result;
},

getHistory() {
  return [...history]; // Return copy
},

clearHistory() {
  history = [];
}

}; })();

Calculator.add(5, 3); // 8 console.log(Calculator.getHistory()); // ["5 + 3 = 8"]

Revealing Module Pattern

Cleaner variation of module pattern:

const UserManager = (function() { // Private let users = [];

function findUserById(id) { return users.find(u => u.id === id); }

function validateUser(user) { return user && user.name && user.email; }

// Public methods function addUser(user) { if (validateUser(user)) { users.push(user); return true; } return false; }

function getUser(id) { return findUserById(id); }

function getAllUsers() { return [...users]; }

// Reveal public API return { add: addUser, get: getUser, getAll: getAllUsers }; })();

Factory Pattern

Create objects without specifying exact class:

function createUser(name, role) { const roles = { admin: { permissions: ['read', 'write', 'delete'], level: 3 }, editor: { permissions: ['read', 'write'], level: 2 }, viewer: { permissions: ['read'], level: 1 } };

const roleConfig = roles[role] || roles.viewer;

return { name, role, ...roleConfig,

hasPermission(permission) {
  return this.permissions.includes(permission);
},

toString() {
  return `${this.name} (${this.role})`;
}

}; }

const admin = createUser('Alice', 'admin'); const editor = createUser('Bob', 'editor');

console.log(admin.hasPermission('delete')); // true console.log(editor.hasPermission('delete')); // false

Singleton Pattern

Ensure only one instance exists:

const Config = (function() { let instance;

function createInstance() { return { apiUrl: 'https://api.example.com', timeout: 5000, retries: 3,

  get(key) {
    return this[key];
  },

  set(key, value) {
    this[key] = value;
  }
};

}

return { getInstance() { if (!instance) { instance = createInstance(); } return instance; } }; })();

const config1 = Config.getInstance(); const config2 = Config.getInstance(); console.log(config1 === config2); // true

// Modern ES6 class version class Database { constructor() { if (Database.instance) { return Database.instance; }

this.connection = null;
Database.instance = this;

}

connect() { if (!this.connection) { this.connection = 'Connected to DB'; } return this.connection; } }

const db1 = new Database(); const db2 = new Database(); console.log(db1 === db2); // true

Observer Pattern

Subscribe to and publish events:

class EventEmitter { constructor() { this.events = {}; }

on(event, listener) { if (!this.events[event]) { this.events[event] = []; } this.events[event].push(listener);

// Return unsubscribe function
return () => this.off(event, listener);

}

off(event, listenerToRemove) { if (!this.events[event]) return;

this.events[event] = this.events[event].filter(
  listener => listener !== listenerToRemove
);

}

emit(event, ...args) { if (!this.events[event]) return;

this.events[event].forEach(listener => {
  listener(...args);
});

}

once(event, listener) { const onceWrapper = (...args) => { listener(...args); this.off(event, onceWrapper); }; this.on(event, onceWrapper); } }

// Usage const emitter = new EventEmitter();

const unsubscribe = emitter.on('data', (data) => { console.log('Received:', data); });

emitter.emit('data', { id: 1 }); // "Received: { id: 1 }" unsubscribe(); emitter.emit('data', { id: 2 }); // Nothing logged

Memoization

Cache function results for performance:

function memoize(fn) { const cache = new Map();

return function(...args) { const key = JSON.stringify(args);

if (cache.has(key)) {
  console.log('Cached result');
  return cache.get(key);
}

const result = fn.apply(this, args);
cache.set(key, result);
return result;

}; }

// Expensive function function fibonacci(n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); }

const memoizedFib = memoize(fibonacci); console.log(memoizedFib(40)); // Slow first time console.log(memoizedFib(40)); // Instant (cached)

// With object methods const calculator = { multiplier: 2,

calculate: memoize(function(n) { return n * this.multiplier; }) };

Best Practices

Naming Conventions

// Constants - UPPERCASE_SNAKE_CASE const MAX_RETRIES = 3; const API_BASE_URL = 'https://api.example.com';

// Variables and functions - camelCase let userName = 'John'; function getUserData() { }

// Classes - PascalCase class UserAccount { } class HTTPHandler { }

// Private convention - prefix with underscore class Widget { constructor() { this._privateProperty = 'internal'; }

_privateMethod() { // Implementation } }

// Boolean variables - use is/has/can prefix const isActive = true; const hasPermission = false; const canEdit = true;

// Functions - use verb prefix function getUser() { } function setConfig() { } function validateInput() { } function handleClick() { }

Error Handling

// Custom error classes class ValidationError extends Error { constructor(message, field) { super(message); this.name = 'ValidationError'; this.field = field; } }

class NetworkError extends Error { constructor(message, statusCode) { super(message); this.name = 'NetworkError'; this.statusCode = statusCode; } }

// Throw specific errors function validateEmail(email) { if (!email.includes('@')) { throw new ValidationError('Invalid email format', 'email'); } return true; }

// Handle different error types try { validateEmail('invalid'); } catch (error) { if (error instanceof ValidationError) { console.error(Validation failed for ${error.field}: ${error.message}); } else { console.error('Unexpected error:', error); } }

// Async error handling async function fetchWithRetry(url, retries = 3) { for (let i = 0; i < retries; i++) { try { const response = await fetch(url); if (!response.ok) { throw new NetworkError('Request failed', response.status); } return await response.json(); } catch (error) { if (i === retries - 1) throw error; // Last retry console.log(Retry ${i + 1}/${retries}); await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } } }

Performance Tips

// 1. Avoid unnecessary operations in loops // Bad for (let i = 0; i < array.length; i++) { } // Length calculated each iteration

// Good const len = array.length; for (let i = 0; i < len; i++) { }

// Better - use built-in methods array.forEach(item => { });

// 2. Debounce expensive operations function debounce(fn, delay) { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn.apply(this, args), delay); }; }

const expensiveSearch = debounce((query) => { // API call }, 300);

// 3. Throttle high-frequency events function throttle(fn, limit) { let inThrottle; return function(...args) { if (!inThrottle) { fn.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; }

window.addEventListener('scroll', throttle(() => { // Handle scroll }, 100));

// 4. Use object/map for lookups // Bad - O(n) const colors = ['red', 'blue', 'green']; colors.includes('blue'); // Linear search

// Good - O(1) const colorSet = new Set(['red', 'blue', 'green']); colorSet.has('blue'); // Constant time

// 5. Avoid memory leaks // Bad - event listener not removed element.addEventListener('click', handler);

// Good const handler = () => { }; element.addEventListener('click', handler); // Later... element.removeEventListener('click', handler);

// 6. Use WeakMap for private data const privateData = new WeakMap();

class MyClass { constructor() { privateData.set(this, { secret: 'value' }); }

getSecret() { return privateData.get(this).secret; } } // When instance is garbage collected, WeakMap entry is too

Code Organization

// 1. Single Responsibility Principle // Bad - function does too much function processUserData(userData) { // Validate // Transform // Save to database // Send email // Update UI }

// Good - separate concerns function validateUser(userData) { } function transformUserData(userData) { } function saveUser(userData) { } function sendWelcomeEmail(user) { } function updateUI(user) { }

// 2. Pure functions (no side effects) // Bad - modifies input function addToCart(cart, item) { cart.items.push(item); return cart; }

// Good - returns new object function addToCart(cart, item) { return { ...cart, items: [...cart.items, item] }; }

// 3. Avoid magic numbers // Bad if (user.role === 2) { }

// Good const ROLES = { ADMIN: 1, EDITOR: 2, VIEWER: 3 };

if (user.role === ROLES.EDITOR) { }

// 4. Use default parameters // Bad function greet(name) { name = name || 'Guest'; return Hello, ${name}; }

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

// 5. Guard clauses for early returns // Bad function processOrder(order) { if (order) { if (order.items.length > 0) { if (order.total > 0) { // Process order } } } }

// Good function processOrder(order) { if (!order) return; if (order.items.length === 0) return; if (order.total <= 0) return;

// Process order }

Memory Management

// 1. Clear timers and intervals const timerId = setTimeout(() => { }, 1000); clearTimeout(timerId);

const intervalId = setInterval(() => { }, 1000); clearInterval(intervalId);

// 2. Remove event listeners const handler = () => { }; element.addEventListener('click', handler); element.removeEventListener('click', handler);

// 3. Set references to null when done let largeData = fetchLargeDataset(); // Use data... largeData = null; // Allow garbage collection

// 4. Use WeakMap/WeakSet for caches const cache = new WeakMap(); let obj = { data: 'value' }; cache.set(obj, 'cached value'); obj = null; // Cache entry automatically removed

// 5. Avoid global variables // Bad var globalUser = { };

// Good - use modules/closures (function() { const user = { }; // Use user locally })();

// 6. Be careful with closures function createHeavyObject() { const heavyData = new Array(1000000);

// Bad - closure keeps heavyData in memory return function() { console.log(heavyData.length); };

// Good - only capture what you need const length = heavyData.length; return function() { console.log(length); }; }

Testing Considerations

// 1. Write testable code - pure functions // Testable function calculateTotal(items) { return items.reduce((sum, item) => sum + item.price, 0); }

// Hard to test - depends on external state function calculateTotal() { return cart.items.reduce((sum, item) => sum + item.price, 0); }

// 2. Dependency injection // Hard to test class UserService { constructor() { this.api = new ApiClient(); } }

// Easy to test - inject dependencies class UserService { constructor(apiClient) { this.api = apiClient; } }

// 3. Avoid side effects // Side effects function processData(data) { console.log('Processing...'); // Side effect updateDatabase(data); // Side effect return transform(data); }

// Pure function transformData(data) { return transform(data); }

// Separate side effects function processData(data) { const transformed = transformData(data); console.log('Processing...'); updateDatabase(transformed); return transformed; }

Quick Reference

Array Methods Cheat Sheet

const arr = [1, 2, 3, 4, 5];

// Transform arr.map(x => x * 2) // [2, 4, 6, 8, 10] arr.filter(x => x > 2) // [3, 4, 5] arr.reduce((sum, x) => sum + x) // 15

// Search arr.find(x => x > 3) // 4 arr.findIndex(x => x > 3) // 3 arr.indexOf(3) // 2 arr.includes(3) // true arr.some(x => x > 3) // true arr.every(x => x > 0) // true

// Mutation arr.push(6) // Add to end arr.pop() // Remove from end arr.unshift(0) // Add to start arr.shift() // Remove from start arr.splice(2, 1, 99) // Remove/add at index

// Non-mutating arr.slice(1, 3) // [2, 3] arr.concat([6, 7]) // [1, 2, 3, 4, 5, 6, 7] [...arr] // Copy arr.join(', ') // "1, 2, 3, 4, 5" arr.reverse() // [5, 4, 3, 2, 1] (mutates!) arr.sort((a, b) => a - b) // Sort (mutates!)

Object Methods Cheat Sheet

const obj = { a: 1, b: 2, c: 3 };

Object.keys(obj) // ['a', 'b', 'c'] Object.values(obj) // [1, 2, 3] Object.entries(obj) // [['a', 1], ['b', 2], ['c', 3]] Object.fromEntries([['a', 1]]) // { a: 1 }

Object.assign({}, obj, { d: 4 }) // { a: 1, b: 2, c: 3, d: 4 } { ...obj, d: 4 } // Same as above

Object.freeze(obj) // Make immutable Object.seal(obj) // Prevent add/remove properties Object.preventExtensions(obj) // Prevent adding properties

Object.hasOwnProperty.call(obj, 'a') // true 'a' in obj // true obj.hasOwnProperty('a') // true (not recommended)

Common Gotchas

// 1. Equality 0 == '0' // true (type coercion) 0 === '0' // false (strict) null == undefined // true null === undefined // false

// 2. Type coercion '5' + 3 // "53" (string concatenation) '5' - 3 // 2 (numeric subtraction) +'5' // 5 (unary plus converts to number) !!'value' // true (double negation to boolean)

// 3. this binding const obj = { name: 'Object', regular: function() { console.log(this.name); }, arrow: () => { console.log(this.name); } }; obj.regular(); // "Object" obj.arrow(); // undefined (arrow uses lexical this)

// 4. Falsy values false, 0, -0, 0n, '', null, undefined, NaN

// 5. Array/Object comparison [] === [] // false (different references) {} === {} // false (different references)

// 6. Floating point 0.1 + 0.2 === 0.3 // false (0.30000000000000004) Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON // true

// 7. Hoisting console.log(x); // undefined (var hoisted) var x = 5;

console.log(y); // ReferenceError (let not hoisted to usable state) let y = 5;

This comprehensive guide covers the essential JavaScript fundamentals needed for modern development. Practice these concepts regularly and refer to the EXAMPLES.md file for detailed implementation scenarios.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

docker-compose-orchestration

No summary provided by upstream source.

Repository SourceNeeds Review
General

postgresql-database-engineering

No summary provided by upstream source.

Repository SourceNeeds Review
General

jest-react-testing

No summary provided by upstream source.

Repository SourceNeeds Review
General

ui-design-patterns

No summary provided by upstream source.

Repository SourceNeeds Review