| Tag | Purpose |
|---|---|
<header> |
Introductory content, site branding, navigation |
<nav> |
Major navigation links |
<main> |
Main unique content (one per page) |
<article> |
Self-contained content (blog post, comment) |
<section> |
Thematic grouping of related content |
<aside> |
Sidebar, related links, supplementary info |
<footer> |
Page footer, copyright, related links |
<figure> |
Self-contained illustration, diagram, photo |
<figcaption> |
Caption for <figure> |
alt text on all images<label> tagsaria-label for icon buttonsrole attributes for custom components| Input Type | Description |
|---|---|
text |
Single-line text input |
password |
Password input (masked) |
email |
Email address input with validation |
number |
Numeric input with optional min/max |
checkbox |
Multiple selection options |
radio |
Single selection from a group |
submit |
Submit the form data |
Remember to use the correct form attributes like:
<section> instead of <div>?
<div> is a generic container with no semantic meaning, while
<section> groups related content that usually has a heading and gives structure to the
page.
<article> and
<section>?
<article> is a self-contained piece of content that should
still make sense on its own, while a <section> groups related content under a common theme.
<span> used for?<span> is an inline element mainly used to style or target
part of a sentence or word without breaking the flow of text.| Promises | Async/Await |
|---|---|
| Chainable with .then/.catch | Syntactic sugar over Promises, reads like sync code |
| Good for parallel flows (Promise.all) | Good for sequential flows and readability |
| Must handle rejections with .catch | Use try/catch for errors |
| Works in older environments with polyfills | Requires async-capable runtime or transpile |
// create 23 promises and await them
const tasks = Array.from({length:23}, (_,i) =>
new Promise((res) => setTimeout(() => res(i+1), 10 + (i%5)*10))
);
// parallel with Promise.all
Promise.all(tasks).then(results => console.log('parallel results', results));
// sequential with async/await
async function runSequential(){
const out = [];
for(const t of tasks){
out.push(await t);
}
console.log('sequential results', out);
}
runSequential();
Shorter syntax; lexical `this` binding.
const nums = [1,2,3];
const squares = nums.map(n => n*n);
const obj = {
val: 10,
getVal: () => this.val // `this` is lexical, not the object
};
`let` and `const` are block-scoped; `const` is immutable binding.
for(let i=0;i<3;i++){
setTimeout(()=>console.log(i), 10); // prints 0,1,2
}
const a = {x:1};
a.x = 2; // allowed; binding immutable, properties mutable
const [a,b=2] = [1];
const {name='anon'} = {};
function f({x=0,y=0} = {}){ return x+y }
const a = [1,2];
const b = [...a,3];
function sum(...nums){ return nums.reduce((s,n)=>s+n,0) }
// module.js
export function add(a,b){ return a+b }
// main.js
import { add } from './module.js';
console.log(add(1,2));
Use localStorage for data that should persist across browser sessions, and
sessionStorage for temporary data that should disappear when the tab closes.
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');
sessionStorage.setItem('step', '2');
class Animal{ constructor(name){ this.name = name } speak(){ return this.name } }
class Dog extends Animal{ bark(){ return 'woof' }}
const d = new Dog('Fido');
const s = new Set([1,2,2]);
const m = new Map([['k', 'v']]);
console.log(s.has(1), m.get('k'));
let x = (5 == "5") // x = true
let y = (5 === "5") // y = false
let y = (5 === "5") // y = false
function* gen(){ yield 1; yield 2 }
const it = gen();
console.log(it.next().value);
| Type | Example |
|---|---|
| number | let age:number = 25; |
| string | let name:string = "Izzy"; |
| boolean | let active:boolean = true; |
| array | let nums:number[] = [1,2,3]; |
| tuple | let user:[string,number] = ["Izzy",54]; |
let age:number = 54;
let name:string = "Izzy";
let scores:number[] = [18,20];
| type | interface |
|---|---|
| Can describe primitives | Objects only |
| Supports unions | No unions |
| Supports intersections | Can extend |
| More flexible | Great for object contracts |
interface User{
id:number;
name:string;
}
type Status =
"loading" | "success" | "error";
interface User{
id:number;
name?:string;
readonly email:string;
}
? optional property
readonly cannot be modified after creation.
type Status =
"loading"
| "success"
| "error";
let state:Status = "loading";
Allows multiple possible types or values.
function identity<T>(value:T):T{
return value;
}
identity(5);
identity("hello");
Reusable types that work with many data types.
| Type | Meaning |
|---|---|
| any | Turns off type checking |
| unknown | Must check type before use |
| never | Function never returns |
let value:unknown;
if(typeof value === "string"){
console.log(value.length);
}
const input =
document.getElementById("name")
as HTMLInputElement;
console.log(input.value);
Tells TypeScript the expected type.
function add(a:number,b:number):number{
return a+b;
}
Always type parameters and return values.
interface User{
id:number;
name:string;
}
async function getUser():
Promise<User>{
return {
id:1,
name:"Izzy"
};
}
Promise<User> means the promise eventually resolves to a User.
type ButtonProps={
title:string;
onClick:()=>void;
}
function Button({
title,
onClick
}:ButtonProps){
return (
<button
onClick={onClick}>
{title}
</button>
);
}
const [user,setUser] =
useState<User|null>(null);
| Question | Answer |
|---|---|
| type vs interface | type is more flexible (unions, intersections, primitives). interface is ideal for describing object shapes and can be extended. |
| any vs unknown | unknown is safer because TypeScript forces you to check the type before using it. |
| null vs undefined | undefined means a variable hasn't been assigned. null is an intentional absence of value. |
| Promise<User> | A Promise that eventually resolves to a User. |
| User[] | An array of User objects. |
| User | null | The value can either be a User object or null. |
| <T> | A generic placeholder type used to make reusable functions and classes. |
const [user, setUser] = useState<User | null>(null);
Selectors are patterns used to select the elements you want to style. Common types include:
div,
p).
.my-class).
#my-id).[type="text"]).
:hover,
:first-child).
::before,
::after).
/* Type Selector */
p {
color: blue;
}
| Position | Description |
|---|---|
| static | Default position; elements flow in the normal document flow. |
| relative | Element is positioned relative to its normal position. |
| absolute | Element is positioned relative to its nearest positioned ancestor. |
| fixed | Element is positioned relative to the viewport and does not move when scrolled. |
| sticky | Element toggles between relative and fixed, depending on the scroll position. |
div {
position: absolute;
top: 10px;
left: 20px;
}
To center a div horizontally and vertically, you can use Flexbox or Grid:
/* Flexbox */
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh; /* Full viewport height */
}
/* Grid */
.container {
display: grid;
place-items: center;
height: 100vh; /* Full viewport height */
}
The CSS box model describes the rectangular boxes generated for elements in the document tree and consists of:
<div class="box-container">
<div class="box">1</div>
<div class="box">2</div>
<!-- repeat for 23 boxes -->
</div>
.box-container { padding: 12px; border: 2px solid #1976d2; }
.box { width: 32px; height: 32px; margin: 4px; padding: 6px; border: 2px solid #1565c0; }
Flexbox is a one-dimensional layout method for arranging items in rows or columns. Key properties include:
<div class="flex-demo">
<div class="box">1</div>
<div class="box">2</div>
<!-- repeat for 23 boxes -->
</div>
.flex-demo {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
CSS Grid is a two-dimensional layout system for creating complex layouts. Key properties include:
<div class="grid-demo">
<div class="box">1</div>
<div class="box">2</div>
<!-- repeat for 23 boxes -->
</div>
.grid-demo {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 8px;
}
| Mechanism | What triggers the update? | When does the component re-render? | Typical useEffect dependency |
|---|---|---|---|
useState |
setState(newValue) |
After the state value changes. | [state] |
useReducer |
dispatch(action) |
After the reducer returns a new state. | [state] or [state.someProperty] |
useContext |
The Provider's value changes. |
Every component consuming that Context re-renders. | [context] or [context.someProperty] |
| Props | The parent renders with different props. | The child component re-renders. | [props.name] |
useEffect |
Nothing. It never starts a render. | It does not trigger a render by itself. | Depends on the dependency array. |
useEffect() runs after React has rendered
and updated the DOM. It reacts to changes; it does not cause them
(unless it calls setState()).
Vanilla JavaScript manipulates the DOM directly with methods like querySelector and
addEventListener. React lets you describe the UI declaratively with components and state, and
it updates the DOM efficiently when state changes.
| Dependency | Runs when... |
|---|---|
[] |
Only once after mount |
[count] |
Whenever count changes |
[user] |
Whenever context/state reference changes |
| No dependency array | After EVERY render |
| Action | Re-render? |
|---|---|
| setState() | β Yes |
| dispatch() | β Yes |
| Context Provider changes | β Yes |
| Props change | β Yes |
| useEffect() | β No* |
* Unless the effect itself calls
setState().
Use useEffect for side effects such as fetching data, subscribing to events, timers, or
syncing with browser APIs like localStorage. It is usually not the right tool for computing
values from existing state during render.
| Context | Reducer |
|---|---|
| Shares state | Updates state |
| Avoids prop drilling | Centralizes logic |
| Who can access? | How does it change? |
A parent component can own state and pass both values and callback functions to children through props. This is a common pattern for controlling behavior from a parent.
function Parent() {
const [count, setCount] = useState(0);
const handleReset = () => setCount(0);
return (
Count: {count}
);
}
function Child({ count, onReset }) {
return ;
}
| Class Component | Functional Component |
|---|---|
| Uses lifecycle methods | Uses hooks |
| Has this.state and this.setState() | Uses useState() hook |
| More boilerplate code | Simpler and more concise |
useContext lets a component read values from a context without passing props through every
level. It is helpful for shared data such as themes, authentication, or user settings.
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
{children}
);
}
function Header() {
const { theme } = useContext(ThemeContext);
return Current theme: {theme}
;
}
Angular supports several binding types:
{{ value }}[src]="imageUrl"(click)="save()"[(ngModel)]@Component({
template: `<h2>{{ title }}</h2>`
})
export class DemoComponent {
title = 'Angular';
}
Services centralize reusable logic and are injected into components via Angular's DI container.
@Injectable({ providedIn: 'root' })
export class UserService {
getUsers() { return ['Ada', 'Grace']; }
}
RxJS lets Angular handle asynchronous streams with observables, operators, and subscriptions.
this.http.get<User[]>('/api/users').subscribe(users => {
this.users = users;
});
Angular updates the UI based on change detection. Using ChangeDetectionStrategy.OnPush can
improve performance by limiting checks.
@Component({
selector: 'app-card',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '{{ name }}
'
})
export class CardComponent { @Input() name = ''; }
The Node.js event loop is a mechanism that allows Node.js to perform non-blocking I/O operations by offloading operations to the system kernel whenever possible.
Node.js uses the CommonJS module system, where each file is treated as a separate module.
import and
export, but it requires the use of the .mjs extension or setting "type": "module" in
package.json.
Streams are a way to handle reading/writing data in chunks, which is efficient for large data sets.
Agentic AI refers to systems that can plan, act autonomously, and manage multi-step tasks using reasoning, tools, and memory.
' OR '1'='1
This would bypass authentication and potentially allow unauthorized access to the application.
<script>alert('XSS Attack!');</script>
When other users view the comment, the script executes in their browsers, potentially stealing cookies or performing other malicious actions.