Browser has a JavaScript engine (V8, SpiderMonkey, JavaScriptCore, etc.), allowing JS to:
Manipulate web pages (DOM)
Handle user events
Communicate with servers (AJAX, Fetch)
Executed line-by-line by the browser or runtime environment.
JavaScript supports:
Imperative programming
Object-oriented programming
Functional programming
It includes features like:
First-class functions
Closures
Higher-order functions
Variable types are determined at runtime.
let x = 10;
x = "hello"; // valid
JavaScript uses prototypes instead of classical inheritance.
Objects can inherit directly from other objects:
const obj = { a: 1 };
const child = Object.create(obj);
Web browsers
Servers (Node.js)
Desktop apps (Electron)
Mobile apps (React Native)
IoT (Johnny-Five)
Modern engines optimize JavaScript using JIT compilation, making it fast.
JavaScript uses a single-threaded event loop, but supports asynchronous operations through:
Callbacks
Promises
async/await
This makes it efficient for:
Networking
Handling user interaction
Non-blocking I/O
Many operations in JavaScript revolve around events:
Clicking a button
Completing an HTTP request
Timer completion
This integrates deeply with the DOM and browser APIs.
Frameworks like React, Angular, Vue
Tooling like Webpack, Babel, ESLint
Hoisting is a JavaScript behavior where variable and function declarations are moved (conceptually) to the top of their scope before the code runs.
This means we can sometimes use a variable or function before it is declared — but what gets hoisted and how depends on whether it’s var, let, const, or a function.
JavaScript engine makes two passes:
Compilation phase → sets up scopes, hoists declarations
Execution phase → runs code top-down
This design helps make functions available throughout their scope.
It removes the silent errors from the code, such as you can't use the variable without declaration, you can't modify the readable property of the object, etc.
To enble strcit mode, write the following literal expression to the top of the code −
'use strict';
It can enabled globally or locally
Scope: Global (if created in non-strict mode. Throws ReferenceError in strict mode ('use strict';)).
Hoisting: Not hoisted because they are never officially declared.
x = 10; // undeclared
console.log(x); // 10
❌ Always avoid undeclared variables; they create bugs and global pollution.
Scope: Function-scoped (not block-scoped).
Hoisting: Yes, hoisted with undefined initialization.
Reassignment: Allowed.
Redeclaration: Allowed in the same scope.
console.log(a); // undefined (hoisted)
var a = 5;
a = 10; // reassign allowed
var a = 20; // redeclare allowed
⚠️ Use var only if you need old function-scoping behavior.
Scope: Block-scoped (inside {}).
Hoisting: Yes, but not initialized → Temporal Dead Zone (TDZ) until the declaration is reached.
Reassignment: Allowed.
Redeclaration: Not allowed in the same scope.
console.log(b); // ReferenceError (TDZ)
let b = 5;
b = 10; // reassign allowed
// let b = 20; // Error: redeclaration not allowed
Scope: Block-scoped.
Hoisting: Yes, but also TDZ applies.
Reassignment: Not allowed.
Redeclaration: Not allowed.
Note: Objects/arrays declared with const can still have their contents modified, only the binding cannot change.
const c = 5;
// c = 10; // Error: assignment not allowed
const obj = { name: 'Alice' };
obj.name = 'Bob'; // Allowed, modifying contents
// obj = {}; // Error, cannot reassign
let a = 42;
let b = 3.14;
let c = Infinity;
let d = NaN; // Not a Number (still a number!)
let big = 123456789012345678901234567890n;
Used for high-precision integer operations.
let s = "Hello";
let name = 'User';
let msg = `Hi ${name}`;
Strings are immutable.
let isReady = true;
let flag = false;
let x;
console.log(x); // ReferenceError: undefined
Also the default value of missing function parameters
let x = null;
let id = Symbol("id");
Often used in libraries/frameworks to create hidden object properties.
let obj = { name: "Alice" };
let arr = [1, 2, 3];
function foo() {}
let now = new Date();
let pattern = /abc/;
let m = new Map();
let s = new Set();
Used for special memory-optimized references.
Used for raw binary data.
class Person {}
"100" + 24; // Converts 24 to string
'100' + false; // Converts false boolean value to string
"100" + null; // Converts null keyword to string
'100' / 50; // Converts '100' to 100
'100' - '50'; // Converts '100' and '50' to 100 and 50
'100' * true; // Converts true to 1
'100' - false; // Converts false to 0
'tp' / 50 // converts 'tp' to NaN
String(100); // number to string
String(null); // null to string
String(true); // boolean to string
Number('100'); // Converts '100' to 100
Number(false); // Converts false to 0
Number(null); // Converts null to 0
num = +"200"; // Using the unary operator
parseFloat(): To extract the floating point number from the string
parseInt(): To extract the integer from the string
Syntax:
typeof value
typeof (value)
Syntax: op1 ?? op2 → returns the op2 if op1 is null or undefined.
let x = null;
let y = x ?? 5; // y = 5;
Syntax: variable ?= value; → if variable is null , it'll be assigned to value.
let username = null;
username ?= "Guest"; // username = "Guest"
It removes the property as well as value of the property from the object. It works only with the objects NOT with the variables or functions.
Deleting Object Property:
const obj = {
product: "Mobile",
price: 20000
}
delete obj.color;
Deleting Array Element:
const arr = [10, 20, 30, 40, 50];
delete arr[1]; // deleting 2nd element from array
Syntax: var answer = (exp1, exp2, ...);
Evaluate multiple expressions from left to right, and returns resultant value of the last expression only.
let a = 5;
let ans = (a = 8, a++, a += 2); // ans = 11
let lang = ("JavaScript", "Python", "HTML"); // lang = "HTML"
When a generator function is called, it returns a generator object.
next() method of this object → it resumes the execution, and pauses at the yield and returns the expression of the yield.
function* test() {
yield 20;
yield [1,2,3];
yield "Hello World";
}
let res = test();
res.next(); // { value: 20, done: false }
res.next(); // { value: [ 1, 2, 3 ], done: false }
res.next(); // { value: 'Hello World', done: false }
res.next(); // { value: undefined, done: true }
let x = ["Hello", "World"];
console.log(x); // [ 'Hello', 'World' ]
console.log(...x); // Hello World
Spread operator to concatenate the arrays:
const nums1 = [1, 2, 0];
const nums2 = [4, 5, 6];
const res = [...nums1, ...nums2];