To run a javascript file we write this in terminal:
node filename.js- Shortcut for
console.log()in vscode is just typelogand hit tab - Using semicolon at the end of the line is optional nowadays in js
Shift + Alt + Ais used to add or remove multi line comments
| Precedence | Operator Type | Operators | Associativity |
|---|---|---|---|
| 20 | Grouping | () |
N/A |
| 19 | Member Access | . |
Left to Right |
| Computed Member | [] |
Left to Right | |
| Function Call | () |
Left to Right | |
| 18 | new (with args) | new |
Right to Left |
| 17 | Postfix Increment | expr++ |
N/A |
| Postfix Decrement | expr-- |
N/A | |
| 16 | Logical NOT | ! |
Right to Left |
| Unary Plus/Minus | +, - |
Right to Left | |
| Prefix Inc/Dec | ++, -- |
Right to Left | |
| typeof, delete, void | typeof, delete, void |
Right to Left | |
| 15 | Exponentiation | ** |
Right to Left |
| 14 | Multiplication/Division/Modulo | *, /, % |
Left to Right |
| 13 | Addition/Subtraction | +, - |
Left to Right |
| 12 | Bitwise Shift | <<, >>, >>> |
Left to Right |
| 11 | Relational | <, <=, >, >=, in, instanceof |
Left to Right |
| 10 | Equality | ==, !=, ===, !== |
Left to Right |
| 9 | Bitwise AND | & |
Left to Right |
| 8 | Bitwise XOR | ^ |
Left to Right |
| 7 | Bitwise OR | ` | ` |
| 6 | Logical AND | && |
Left to Right |
| 5 | Logical OR | ` | |
| 4 | Nullish Coalescing | ?? |
Left to Right |
| 3 | Conditional (ternary) | ? : |
Right to Left |
| 2 | Assignment | =, +=, -=, *=, etc. |
Right to Left |
| 1 | Comma | , |
Left to Right |
Difference between == === and != !== and when and where we use them:
| Operator | Name | Compares | Performs Type Conversion? | Example |
|---|---|---|---|---|
== |
Equal to | Value only | ✅ Yes | '5' == 5 → true |
=== |
Strict Equal to | Value + Type | ❌ No | '5' === 5 → false |
!= |
Not Equal to | Value only | ✅ Yes | '5' != 5 → false |
!== |
Strict Not Equal to | Value + Type | ❌ No | '5' !== 5 → true |
Converts both values to the same type before comparing.
"10" == 10; // true
false == 0; // true
null == undefined; // trueNo type conversion — values must be same type and value.
"10" === 10; // false
false === 0; // false
null === undefined; // falseHoisting is JavaScript's behavior of moving declarations to the top of their scope (before code is executed).
It's like JS saying:
"I'll take all your
var,function, and certainclassdeclarations and put them at the top in my memory before running your code."
- During compilation, JS scans your code first (before running it).
- It remembers variable and function declarations, but not assignments.
- Then it runs your code line by line.
console.log(a); // undefined, NOT error
var a = 5;
console.log(a); // 5Why? JavaScript actually treats it like:
var a; // declaration moved to top
console.log(a); // undefined
a = 5; // assignment stays here
console.log(a); // 5console.log(b); // ❌ ReferenceError
let b = 10;
console.log(c); // ❌ ReferenceError
const c = 20;Why?
letandconstare also hoisted but placed in a Temporal Dead Zone (TDZ) — a phase where the variable exists but can't be used until it's declared in code.
sayHi(); // "Hello!"
function sayHi() {
console.log("Hello!");
}Why? Function declarations are hoisted with their entire body, so you can call them before they appear.
sayHello(); // ❌ TypeError: sayHello is not a function
var sayHello = function () {
console.log("Hello!");
};Here:
var sayHellois hoisted (initialized asundefined).- You try to call
undefined()→ TypeError.
With let or const:
sayHello(); // ❌ ReferenceError
let sayHello = function () {
console.log("Hello!");
};This hits the TDZ again.
| Declaration Type | Hoisted? | Initialized? | Can Use Before Declared? |
|---|---|---|---|
var |
✅ Yes | undefined |
Yes (but undefined) |
let |
✅ Yes | No (TDZ) | ❌ No |
const |
✅ Yes | No (TDZ) | ❌ No |
function (decl) |
✅ Yes | Full body | ✅ Yes |
| Function expr. | ✅ Yes (var)/TDZ(let/const) | undefined or No | ❌ No |
💡 In Short:
Hoisting means declarations are moved to the top of their scope during compilation, but initializations stay where they are.
console.log(a);
console.log(b);
console.log(c);
var a = 10;
let b = 20;
const c = 30;
sayHi();
function sayHi() {
console.log("Hi!");
}
sayHello();
var sayHello = function () {
console.log("Hello!");
};JS scans the whole code first:
| Name | Value in Memory (Before Execution) | Notes |
|---|---|---|
a |
undefined |
var is hoisted & initialized as undefined |
b |
uninitialized (TDZ) | let is hoisted but not initialized |
c |
uninitialized (TDZ) | const is hoisted but not initialized |
sayHi |
function code (full body) | function declarations are hoisted with body |
sayHello |
undefined |
function expression with var behaves like a normal var |
console.log(a)→undefined(becausevar ais hoisted & set to undefined)console.log(b)→ ❌ ReferenceError (b is in TDZ)console.log(c)→ ❌ ReferenceError (c is in TDZ)a = 10;→anow has value10b = 20;→binitialized, TDZ ends forbc = 30;→cinitialized, TDZ ends forcsayHi();→"Hi!"(function declaration works before definition)sayHello();→ ❌ TypeError:sayHelloisundefined(var was hoisted but assigned later)
Before execution starts:
Global Scope Memory:
a → undefined
b → TDZ
c → TDZ
sayHi → function sayHi() { console.log("Hi!"); }
sayHello → undefined
During execution:
console.log(a) → undefined
console.log(b) → ReferenceError (TDZ)
console.log(c) → ReferenceError (TDZ)
a = 10
b = 20
c = 30
sayHi() → "Hi!"
sayHello() → TypeError: undefined is not a function
Scope determines where in your code a variable can be accessed.
Think of scope like "the visibility range" of a variable.
- Declared outside of any function or block.
- Accessible anywhere in the file after declaration.
var globalVar = "I am global";
function showGlobal() {
console.log(globalVar); // ✅ Works
}
showGlobal();
console.log(globalVar); // ✅ Works- Variables declared inside a function are only accessible within that function.
- Applies to
var,let, andconst(but block scope rules still apply toletandconstinside sub-blocks).
function myFunction() {
var funcVar = "I live inside a function";
console.log(funcVar); // ✅ Works
}
myFunction();
console.log(funcVar); // ❌ Error: not defined- A block = anything inside
{ }(loops, if statements, etc.). letandconstare block scoped,varis not.
if (true) {
var varTest = "I ignore blocks";
let letTest = "I am block scoped";
const constTest = "Me too!";
}
console.log(varTest); // ✅ Works
console.log(letTest); // ❌ Error
console.log(constTest); // ❌ Error- Functions can access variables from their outer scope.
- This is the basis for closures.
function outer() {
let outerVar = "I am from outer";
function inner() {
console.log(outerVar); // ✅ Access outer scope
}
inner();
}
outer();When you try to access a variable, JS looks:
- In the current scope
- If not found → In the outer scope
- Repeats until global scope
- If still not found → ReferenceError
The chain only works from inside to outside not the other way
let globalName = "Sneha";
function outer() {
let outerName = "Hitesh";
function inner() {
let innerName = "JavaScript";
console.log(innerName); // Found in inner
console.log(outerName); // Found in outer
console.log(globalName); // Found in global
}
inner();
}
outer();| Feature | var |
let / const |
|---|---|---|
| Scope type | Function scope | Block scope |
| Hoisted | Yes, undefined |
Yes, TDZ |
| Redeclaration | Allowed | Not allowed |
The ?? operator returns the right-hand value only if the left-hand value is null or undefined, otherwise it returns the left-hand value.
👉 Unlike the || (OR) operator, it does not treat false, 0, or empty string "" as fallback conditions.
let userColor = undefined;
let defaultColor = "blue";
let currentColor = userColor ?? defaultColor;
console.log(currentColor); // Output: "blue"✅ Because userColor is undefined, ?? takes the right side ("blue").
let userColor = "red";
let defaultColor = "blue";
let currentColor = userColor ?? defaultColor;
console.log(currentColor); // Output: "red"✅ Because userColor is neither null nor undefined, ?? returns "red".
let userColor = "";
let defaultColor = "blue";
let currentColor1 = userColor || defaultColor; // OR operator
let currentColor2 = userColor ?? defaultColor; // Nullish coalescing
console.log(currentColor1); // "blue" (because "" is falsy)
console.log(currentColor2); // "" (because "" is NOT null/undefined)👉 Key difference:
||treats falsy values (false,0,"",NaN) as if they don't exist.??only treatsnullandundefinedas missing values.
⚡ In short:
- Use
||when you want to provide defaults for any falsy value. - Use
??when you want to provide defaults **only for