Master JavaScript with our comprehensive collection of interview questions. Track your progress and get ready for success!
0/100
Questions (0%)
0/40
Easy
0/58
Medium
0/2
Hard
==
compares two values for equality after converting both values to a common type (type coercion).
===
compares both value and type (strict equality).
console.log(5 == '5'); // true - because of type coercion
console.log(5 === '5'); // false - different types
console.log(null == undefined); // true
console.log(null === undefined); // false
A closure is the combination of a function and the lexical environment within which that function was declared. It allows the function to access variables from an outer function after the outer function has closed.
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
var
: Function-scoped, can be redeclared and updated, hoisted with undefinedlet
: Block-scoped, can be updated but not redeclared, hoisted but not initializedconst
: Block-scoped, cannot be updated or redeclared, hoisted but not initializedfunction example() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // Same variable
let b = 5; // Different variable
// const c = 6; // Error: already declared
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's behavior of moving declarations to the top of their scope during compilation. Variables and functions are hoisted, but only declarations, not initializations.
console.log(x); // undefined (not ReferenceError)
var x = 5;
// Above code is interpreted as:
var x;
console.log(x); // undefined
x = 5;
// Function hoisting
console.log(myFunc()); // "Hello!" - works
function myFunc() {
return "Hello!";
}
Arrow functions are a concise way to write functions. They don't have their own this
, arguments
, or super
bindings.
// Regular function
function add(a, b) {
return a + b;
}
// Arrow function
const add = (a, b) => a + b;
// 'this' behavior difference
const obj = {
name: 'John',
regular: function() {
console.log(this.name); // 'John'
},
arrow: () => {
console.log(this.name); // undefined (inherits from outer scope)
}
};
this
refers to the object that is executing the current function. Its value depends on how the function is called.
const person = {
name: 'Alice',
greet: function() {
console.log(this.name); // 'Alice'
}
};
person.greet(); // 'Alice'
const greetFunc = person.greet;
greetFunc(); // undefined (global context)
// Using bind
const boundGreet = person.greet.bind(person);
boundGreet(); // 'Alice'
undefined
: A variable has been declared but not assigned a valuenull
: An intentional absence of any valuelet a;
console.log(a); // undefined
let b = null;
console.log(b); // null
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object' (this is a known bug)
console.log(undefined == null); // true
console.log(undefined === null); // false
JavaScript has two categories of data types: Primitive: Number, String, Boolean, Undefined, Null, Symbol, BigInt Non-primitive: Object (includes arrays, functions, dates, etc.)
// Primitive types
let num = 42; // Number
let str = "Hello"; // String
let bool = true; // Boolean
let undef = undefined; // Undefined
let nullVal = null; // Null
let sym = Symbol('id'); // Symbol
let bigInt = 123n; // BigInt
// Non-primitive types
let obj = {name: 'John'}; // Object
let arr = [1, 2, 3]; // Array
let func = function() {}; // Function
slice()
: Returns a shallow copy of a portion of an array (doesn't modify original)splice()
: Changes the contents of an array by removing/adding elements (modifies original)let arr = [1, 2, 3, 4, 5];
// slice(start, end) - doesn't modify original
let sliced = arr.slice(1, 3);
console.log(sliced); // [2, 3]
console.log(arr); // [1, 2, 3, 4, 5] - unchanged
// splice(start, deleteCount, item1, item2, ...)
let spliced = arr.splice(1, 2, 'a', 'b');
console.log(spliced); // [2, 3] - removed elements
console.log(arr); // [1, 'a', 'b', 4, 5] - modified
Event Bubbling: Events propagate from the target element up to the root Event Capturing: Events propagate from the root down to the target element
// HTML: <div id="outer"><div id="inner">Click me</div></div>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
// Bubbling (default)
outer.addEventListener('click', () => console.log('Outer'));
inner.addEventListener('click', () => console.log('Inner'));
// Click inner: "Inner" then "Outer"
// Capturing
outer.addEventListener('click', () => console.log('Outer'), true);
inner.addEventListener('click', () => console.log('Inner'), true);
// Click inner: "Outer" then "Inner"
forEach()
: Executes a function for each array element, returns undefinedmap()
: Creates a new array with the results of calling a function for each elementconst numbers = [1, 2, 3, 4];
// forEach - no return value
const result1 = numbers.forEach(num => num * 2);
console.log(result1); // undefined
// map - returns new array
const result2 = numbers.map(num => num * 2);
console.log(result2); // [2, 4, 6, 8]
console.log(numbers); // [1, 2, 3, 4] - original unchanged
A Promise is an object representing the eventual completion or failure of an asynchronous operation. It has three states: pending, fulfilled, or rejected.
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve('Operation successful!');
} else {
reject('Operation failed!');
}
});
// Using the Promise
myPromise
.then(result => console.log(result)) // 'Operation successful!'
.catch(error => console.log(error))
.finally(() => console.log('Promise completed'));
async/await
is syntactic sugar for working with Promises. async
declares an asynchronous function, await
pauses execution until the Promise resolves.
// Using Promises
function fetchData() {
return fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.log(error));
}
// Using async/await
async function fetchDataAsync() {
try {
const response = await fetch('/api/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
All three methods are used to set the this
context:
call()
: Invokes function immediately with arguments passed individuallyapply()
: Invokes function immediately with arguments as an arraybind()
: Returns a new function with bound this
contextconst person = { name: 'John' };
function greet(greeting, punctuation) {
console.log(greeting + ' ' + this.name + punctuation);
}
// call - arguments individually
greet.call(person, 'Hello', '!'); // 'Hello John!'
// apply - arguments as array
greet.apply(person, ['Hi', '?']); // 'Hi John?'
// bind - returns new function
const boundGreet = greet.bind(person);
boundGreet('Hey', '!!!'); // 'Hey John!!!'
Destructuring is a syntax that allows you to extract values from arrays or properties from objects into distinct variables.
// Array destructuring
const colors = ['red', 'green', 'blue'];
const [first, second, third] = colors;
console.log(first); // 'red'
console.log(second); // 'green'
// Object destructuring
const person = { name: 'John', age: 30, city: 'New York' };
const { name, age } = person;
console.log(name); // 'John'
console.log(age); // 30
// With default values
const { name: personName, country = 'USA' } = person;
console.log(personName); // 'John'
console.log(country); // 'USA'
The spread operator (...) allows an iterable to be expanded in places where zero or more arguments or elements are expected.
// Array spreading
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// Object spreading
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
// Function arguments
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
The rest parameter (...) allows a function to accept an indefinite number of arguments as an array.
// Rest parameters in functions
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(1, 2)); // 3
// Rest with other parameters
function greet(greeting, ...names) {
return greeting + ' ' + names.join(', ');
}
console.log(greet('Hello', 'John', 'Jane', 'Bob')); // 'Hello John, Jane, Bob'
// Rest in destructuring
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]
A callback function is a function passed as an argument to another function, which is then invoked inside the outer function to complete some kind of routine or action.
// Simple callback
function greet(name, callback) {
console.log('Hello ' + name);
callback();
}
function sayGoodbye() {
console.log('Goodbye!');
}
greet('John', sayGoodbye);
// Output: 'Hello John'
// 'Goodbye!'
// Array method callbacks
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(function(num) {
return num * 2;
});
console.log(doubled); // [2, 4, 6, 8, 10]
// Synchronous code
console.log('First');
console.log('Second');
console.log('Third');
// Output: First, Second, Third (in order)
// Asynchronous code
console.log('First');
setTimeout(() => console.log('Second'), 1000);
console.log('Third');
// Output: First, Third, Second (after 1 second)
// Async/await makes async code look synchronous
async function example() {
console.log('Start');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('End');
}
JSON (JavaScript Object Notation) is a lightweight data interchange format. JavaScript provides JSON.stringify()
and JSON.parse()
methods to work with JSON.
// JavaScript object
const person = {
name: 'John',
age: 30,
city: 'New York'
};
// Convert to JSON string
const jsonString = JSON.stringify(person);
console.log(jsonString); // '{"name":"John","age":30,"city":"New York"}'
// Parse JSON string back to object
const parsedObject = JSON.parse(jsonString);
console.log(parsedObject); // { name: 'John', age: 30, city: 'New York' }
// With arrays
const arr = [1, 2, 3];
console.log(JSON.stringify(arr)); // '[1,2,3]'
// localStorage - persists across sessions
localStorage.setItem('username', 'john_doe');
localStorage.setItem('theme', 'dark');
// Retrieve from localStorage
const username = localStorage.getItem('username');
console.log(username); // 'john_doe'
// sessionStorage - only for current session
sessionStorage.setItem('cartItems', '5');
const items = sessionStorage.getItem('cartItems');
console.log(items); // '5'
// Remove items
localStorage.removeItem('username');
sessionStorage.clear(); // clears all session storage
Template literals are string literals allowing embedded expressions, multi-line strings, and string interpolation using backticks (`).
const name = 'John';
const age = 30;
// Traditional string concatenation
const message1 = 'Hello, my name is ' + name + ' and I am ' + age + ' years old.';
// Template literal
const message2 = `Hello, my name is ${name} and I am ${age} years old.`;
// Multi-line strings
const multiLine = `
This is a
multi-line
string
`;
// Expression evaluation
const calculation = `The sum of 5 and 3 is ${5 + 3}`;
console.log(calculation); // 'The sum of 5 and 3 is 8'
// Function declaration - hoisted
console.log(sayHello()); // 'Hello!' - works due to hoisting
function sayHello() {
return 'Hello!';
}
// Function expression - not hoisted
console.log(sayGoodbye()); // TypeError: sayGoodbye is not a function
var sayGoodbye = function() {
return 'Goodbye!';
};
// Named function expression
const namedFunc = function myFunc() {
return 'Named function';
};
// Arrow function expression
const arrowFunc = () => 'Arrow function';
The Event Loop is what allows JavaScript to perform non-blocking operations by offloading operations to the system kernel or web APIs, then handling callbacks when operations complete.
console.log('Start');
setTimeout(() => {
console.log('Timeout');
}, 0);
Promise.resolve().then(() => {
console.log('Promise');
});
console.log('End');
// Output:
// Start
// End
// Promise
// Timeout
// Microtasks (Promises) have higher priority than macrotasks (setTimeout)
Prototypal inheritance allows objects to inherit properties and methods from other objects through the prototype chain.
// Constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
// Adding method to prototype
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
// Creating instances
const person1 = new Person('John', 30);
const person2 = new Person('Jane', 25);
console.log(person1.greet()); // 'Hello, I\'m John'
console.log(person2.greet()); // 'Hello, I\'m Jane'
// Inheritance
function Student(name, age, grade) {
Person.call(this, name, age);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Modules allow you to break up your code into separate files and share code between files using export
and import
statements.
// math.js - exporting module
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export default function multiply(a, b) {
return a * b;
}
// main.js - importing module
import multiply, { add, subtract } from './math.js';
console.log(add(5, 3)); // 8
console.log(subtract(5, 3)); // 2
console.log(multiply(5, 3)); // 15
// Import all
import * as math from './math.js';
console.log(math.add(2, 3)); // 5
for...in
: Iterates over enumerable properties (keys) of an objectfor...of
: Iterates over iterable objects (values) like arrays, strings, mapsconst array = ['a', 'b', 'c'];
const object = { x: 1, y: 2, z: 3 };
// for...in - iterates over keys/indices
for (let key in array) {
console.log(key); // '0', '1', '2'
}
for (let key in object) {
console.log(key); // 'x', 'y', 'z'
}
// for...of - iterates over values
for (let value of array) {
console.log(value); // 'a', 'b', 'c'
}
// for...of with string
for (let char of 'hello') {
console.log(char); // 'h', 'e', 'l', 'l', 'o'
}
A higher-order function is a function that takes other functions as arguments or returns a function as its result.
// Function that takes another function as argument
function operate(a, b, operation) {
return operation(a, b);
}
function add(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
console.log(operate(5, 3, add)); // 8
console.log(operate(5, 3, multiply)); // 15
// Function that returns a function
function createMultiplier(multiplier) {
return function(number) {
return number * multiplier;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
const original = {
name: 'John',
address: {
city: 'New York',
zip: '10001'
}
};
// Shallow copy
const shallowCopy = { ...}
ES6 classes are syntactical sugar over JavaScript's existing prototype-based inheritance. They provide a cleaner syntax for creating objects and implementing inheritance.
// Class declaration
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
static species() {
return 'Homo sapiens';
}
}
// Inheritance
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
study() {
return `${this.name} is studying`;
}
}
const student = new Student('John', 20, 'A');
console.log(student.greet()); // 'Hello, I\'m John'
console.log(student.study()); // 'John is studying'
console.log(Person.species()); // 'Homo sapiens'
setTimeout
: Executes a function once after a specified delaysetInterval
: Repeatedly executes a function at specified intervals// setTimeout - executes once
const timeoutId = setTimeout(() => {
console.log('This runs once after 2 seconds');
}, 2000);
// Clear timeout if needed
clearTimeout(timeoutId);
// setInterval - executes repeatedly
const intervalId = setInterval(() => {
console.log('This runs every 1 second');
}, 1000);
// Stop interval after 5 seconds
setTimeout(() => {
clearInterval(intervalId);
console.log('Interval stopped');
}, 5000);
push()
: Adds elements to the end of an array and modifies the original arrayconcat()
: Creates a new array by combining arrays, doesn't modify originalsconst arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// push() - modifies original array
const pushResult = arr1.push(4, 5);
console.log(arr1); // [1, 2, 3, 4, 5]
console.log(pushResult); // 5 (new length)
// concat() - returns new array
const arr3 = [1, 2, 3];
const concatResult = arr3.concat([4, 5, 6]);
console.log(arr3); // [1, 2, 3] (unchanged)
console.log(concatResult); // [1, 2, 3, 4, 5, 6]
// concat with multiple arrays
const combined = arr1.concat(arr2, [7, 8]);
console.log(combined); // [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]
Object.freeze()
: Makes an object immutable (can't add, remove, or modify properties)Object.seal()
: Prevents adding/removing properties but allows modifying existing onesconst obj1 = { name: 'John', age: 30 };
const obj2 = { name: 'Jane', age: 25 };
// Object.freeze()
Object.freeze(obj1);
obj1.name = 'Bob'; // Ignored
obj1.city = 'NYC'; // Ignored
delete obj1.age; // Ignored
console.log(obj1); // { name: 'John', age: 30 }
// Object.seal()
Object.seal(obj2);
obj2.name = 'Alice'; // Allowed
obj2.city = 'LA'; // Ignored
delete obj2.age; // Ignored
console.log(obj2); // { name: 'Alice', age: 25 }
// Check status
console.log(Object.isFrozen(obj1)); // true
console.log(Object.isSealed(obj2)); // true
Currying is a technique of transforming a function with multiple arguments into a sequence of functions, each taking a single argument.
// Regular function
function add(a, b, c) {
return a + b + c;
}
// Curried function
function curriedAdd(a) {
return function(b) {
return function(c) {
return a + b + c;
};
};
}
// Usage
console.log(add(1, 2, 3)); // 6
console.log(curriedAdd(1)(2)(3)); // 6
// Partial application
const add5 = curriedAdd(5);
const add5and3 = add5(3);
console.log(add5and3(2)); // 10
// Arrow function currying
const multiply = a => b => c => a * b * c;
console.log(multiply(2)(3)(4)); // 24
Both convert array-like objects to arrays, but Array.from()
is more versatile and can accept a mapping function.
// Array-like object
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
// Array.from()
const arr1 = Array.from(arrayLike);
console.log(arr1); // ['a', 'b', 'c']
// Spread operator
const arr2 = [...arrayLike]; // TypeError: arrayLike is not iterable
// String conversion
const str = 'hello';
console.log(Array.from(str)); // ['h', 'e', 'l', 'l', 'o']
console.log([...str]); // ['h', 'e', 'l', 'l', 'o']
// Array.from with mapping function
const numbers = Array.from({ length: 5 }, (_, i) => i + 1);
console.log(numbers); // [1, 2, 3, 4, 5]
// Set conversion
const set = new Set([1, 2, 3]);
console.log(Array.from(set)); // [1, 2, 3]
console.log([...set]); // [1, 2, 3]
Debouncing delays the execution of a function until after a specified time has elapsed since the last time it was invoked.
// Debounce function
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
// Usage example - search input
const searchInput = document.getElementById('search');
function handleSearch(event) {
console.log('Searching for:', event.target.value);
// API call would go here
}
// Debounced version - only calls after 300ms of no typing
const debouncedSearch = debounce(handleSearch, 300);
searchInput.addEventListener('input', debouncedSearch);
// Without debouncing: called on every keystroke
// With debouncing: called only after user stops typing
Throttling limits the number of times a function can be called over time. It ensures the function executes at most once per specified interval.
// Throttle function
function throttle(func, delay) {
let lastCallTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastCallTime >= delay) {
lastCallTime = now;
func.apply(this, args);
}
};
}
// Usage example - scroll event
function handleScroll() {
console.log('Scroll event triggered');
// Expensive operation here
}
// Throttled version - executes at most once every 100ms
const throttledScroll = throttle(handleScroll, 100);
window.addEventListener('scroll', throttledScroll);
// Without throttling: called hundreds of times per second
// With throttling: called at most 10 times per second
Both ==
and ===
check reference equality for arrays, not content equality. Arrays are objects and compared by reference.
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const arr3 = arr1;
// Reference comparison
console.log(arr1 == arr2); // false (different objects)
console.log(arr1 === arr2); // false (different objects)
console.log(arr1 === arr3); // true (same reference)
// Content comparison methods
// Method 1: JSON.stringify (works for simple arrays)
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)); // true
// Method 2: Custom comparison function
function arraysEqual(a, b) {
return a.length === b.length && a.every((val, i) => val === b[i]);
}
console.log(arraysEqual(arr1, arr2)); // true
// Method 3: Using every()
console.log(arr1.every((val, i) => val === arr2[i]) && arr1.length === arr2.length); // true
Memoization is an optimization technique that stores the results of expensive function calls and returns cached results when the same inputs occur again.
// Simple memoization function
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
console.log('Cache hit!');
return cache.get(key);
}
console.log('Computing...');
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);
}
// Memoized version
const memoizedFib = memoize(fibonacci);
console.log(memoizedFib(10)); // Computing... 55
console.log(memoizedFib(10)); // Cache hit! 55
Object.keys()
: Returns an array of object's property namesObject.values()
: Returns an array of object's property valuesObject.entries()
: Returns an array of [key, value] pairsconst person = {
name: 'John',
age: 30,
city: 'New York'
};
// Object.keys()
const keys = Object.keys(person);
console.log(keys); // ['name', 'age', 'city']
// Object.values()
const values = Object.values(person);
console.log(values); // ['John', 30, 'New York']
// Object.entries()
const entries = Object.entries(person);
console.log(entries); // [['name', 'John'], ['age', 30], ['city', 'New York']]
// Practical usage
// Convert object to Map
const map = new Map(Object.entries(person));
// Iterate over object
Object.entries(person).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
Array.some()
: Returns true if at least one element passes the testArray.every()
: Returns true if all elements pass the testconst numbers = [1, 2, 3, 4, 5];
const mixed = [1, 2, 3, -1, 5];
// Array.some() - at least one element satisfies condition
console.log(numbers.some(n => n > 3)); // true (4 and 5 are > 3)
console.log(numbers.some(n => n > 10)); // false (none > 10)
// Array.every() - all elements must satisfy condition
console.log(numbers.every(n => n > 0)); // true (all positive)
console.log(mixed.every(n => n > 0)); // false (-1 is not > 0)
// Practical examples
const users = [
{ name: 'John', age: 25 },
{ name: 'Jane', age: 17 },
{ name: 'Bob', age: 30 }
];
const hasMinor = users.some(user => user.age < 18);
console.log(hasMinor); // true
const allAdults = users.every(user => user.age >= 18);
console.log(allAdults); // false
slice()
: Extracts a section of string, supports negative indicessubstring()
: Extracts characters between two indices, swaps if start > endconst str = 'Hello World';
// slice(start, end)
console.log(str.slice(0, 5)); // 'Hello'
console.log(str.slice(6)); // 'World'
console.log(str.slice(-5)); // 'World' (from end)
console.log(str.slice(-5, -1)); // 'Worl'
// substring(start, end)
console.log(str.substring(0, 5)); // 'Hello'
console.log(str.substring(6)); // 'World'
console.log(str.substring(-5)); // 'Hello World' (treats negative as 0)
console.log(str.substring(5, 0)); // 'Hello' (swaps arguments)
// Key differences
console.log(str.slice(5, 0)); // '' (empty string)
console.log(str.substring(5, 0)); // 'Hello' (swaps to (0, 5))
innerHTML
: Gets/sets HTML content inside an elementtextContent
: Gets/sets only the text content, ignoring HTML tags// HTML: <div id="myDiv">Hello <strong>World</strong>!</div>
const div = document.getElementById('myDiv');
// innerHTML - includes HTML tags
console.log(div.innerHTML); // 'Hello <strong>World</strong>!'
// textContent - only text, no HTML
console.log(div.textContent); // 'Hello World!'
// Setting content
div.innerHTML = 'New <em>HTML</em> content';
// Result: New HTML content (with emphasis)
div.textContent = 'New <em>text</em> content';
// Result: New <em>text</em> content (tags shown as text)
// Security consideration
const userInput = '<script>alert("XSS")</script>';
div.innerHTML = userInput; // Dangerous - executes script
div.textContent = userInput; // Safe - shows as text
Both invoke a function with a specific this
context, but differ in how arguments are passed:
call()
: Arguments passed individuallyapply()
: Arguments passed as an arrayfunction greet(greeting, punctuation) {
console.log(greeting + ' ' + this.name + punctuation);
}
const person = { name: 'John' };
// call() - arguments individually
greet.call(person, 'Hello', '!');
// Output: 'Hello John!'
// apply() - arguments as array
greet.apply(person, ['Hi', '?']);
// Output: 'Hi John?'
// Practical use case - finding max in array
const numbers = [1, 5, 3, 9, 2];
// Using apply with Math.max
const max = Math.max.apply(null, numbers);
console.log(max); // 9
// Modern alternative with spread operator
const max2 = Math.max(...numbers);
console.log(max2); // 9
// Object
const obj = {
name: 'John',
age: 30,
1: 'number key'
};
// Map
const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.set(1, 'number key');
map.set(true, 'boolean key');
map.set({ id: 1 }, 'object key');
// Key differences
console.log(Object.keys(obj).length); // 3
console.log(map.size); // 5
// Iteration
for (let [key, value] of map) {
console.log(key, value);
}
// Map methods
console.log(map.has('name')); // true
console.log(map.get('name')); // 'John'
map.delete('age');
map.clear(); // removes all
// Performance: Map is generally faster for frequent additions/deletions
// Array - allows duplicates
const arr = [1, 2, 2, 3, 3, 3];
console.log(arr); // [1, 2, 2, 3, 3, 3]
console.log(arr[0]); // 1 (indexed access)
// Set - only unique values
const set = new Set([1, 2, 2, 3, 3, 3]);
console.log(set); // Set(3) {1, 2, 3}
console.log(set.size); // 3
// Set methods
set.add(4);
console.log(set.has(2)); // true
set.delete(1);
// Convert between Set and Array
const uniqueArray = [...set];
const arrayFromSet = Array.from(set);
// Remove duplicates from array
const numbers = [1, 2, 2, 3, 3, 4];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4]
// Iteration
for (let value of set) {
console.log(value);
}
async/await
is syntactic sugar built on top of Promises, making asynchronous code look and behave more like synchronous code.
// Promise-based approach
function fetchUserData() {
return fetch('/api/user')
.then(response => response.json())
.then(user => {
console.log('User:', user);
return fetch(`/api/posts/${user.id}`);
})
.then(response => response.json())
.then(posts => {
console.log('Posts:', posts);
return posts;
})
.catch(error => {
console.error('Error:', error);
});
}
// Async/await approach
async function fetchUserDataAsync() {
try {
const response = await fetch('/api/user');
const user = await response.json();
console.log('User:', user);
const postsResponse = await fetch(`/api/posts/${user.id}`);
const posts = await postsResponse.json();
console.log('Posts:', posts);
return posts;
} catch (error) {
console.error('Error:', error);
}
}
// Both return Promises
console.log(fetchUserData()); // Promise
console.log(fetchUserDataAsync()); // Promise
Regular expressions provide powerful pattern matching capabilities, while string methods offer simpler, more straightforward text operations.
const text = 'Hello World! How are you today?';
const email = 'user@example.com';
// String methods - simple operations
console.log(text.includes('World')); // true
console.log(text.indexOf('How')); // 13
console.log(text.replace('Hello', 'Hi')); // 'Hi World! How are you today?'
// Regular expressions - pattern matching
const regex = /\b\w{3}\b/g; // words with exactly 3 characters
console.log(text.match(regex)); // ['How', 'are', 'you']
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test(email)); // true
// Complex replacements
const phoneNumber = '123-456-7890';
const formatted = phoneNumber.replace(/(\d{3})-(\d{3})-(\d{4})/, '($1) $2-$3');
console.log(formatted); // '(123) 456-7890'
// Case-insensitive search
const caseInsensitive = /hello/i;
console.log(caseInsensitive.test('HELLO')); // true
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
var
, let
, and const
are used to declare variables in JavaScript, but they behave differently:
var
is function-scoped and can be redeclared and updated.let
is block-scoped, can be updated but not redeclared in the same scope.const
is block-scoped, and cannot be updated or redeclared.Example:
function testVarLetConst() {
var a = 1;
let b = 2;
const c = 3;
if (true) {
var a = 4; // same variable
let b = 5; // new variable
// c = 6; // Error: Assignment to constant variable
console.log(b); // 5
}
console.log(a); // 4
console.log(b); // 2
console.log(c); // 3
}
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope during the compilation phase.
Only declarations are hoisted, not initializations.
Example:
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I am hoisted!"
function hoistedFunction() {
console.log("I am hoisted!");
}
In the example above, the declaration of x
and the function hoistedFunction
are hoisted to the top of their scope.
Keep practicing and good luck with your JavaScript interviews! 🚀
Progress
0/100 completed
0% Complete