π Understanding Loops
Loops in JavaScript are used to execute a block of code repeatedly without writing the same code multiple times. They are especially useful when you need to perform the same task over and over, often with different values, making your code shorter, cleaner, and more efficient.
π° for Loop
The for loop repeats a block of code a specific number of times. It contains initialization, condition, and increment/decrement in one line.
Syntax :
for (initialization; condition; increment/decrement) {
// Code to execute
}<div class="infographic-jsfor">
<style>
.infographic-jsfor {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 680px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsfor[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsfor * { box-sizing: border-box; }
.infographic-jsfor .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsfor .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsfor .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jsfor .ig-code strong { color: var(--accent); }
.infographic-jsfor .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsfor .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsfor .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsfor .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsfor .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsfor .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsfor .stage svg { width: 100%; max-width: 560px; height: auto; overflow: visible; }
.infographic-jsfor .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsfor .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsfor .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsfor .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsfor .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsfor .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsfor .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsfor .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsfor .fc-text.on-block { font-weight: 700; }
.infographic-jsfor .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsfor .fc-mark.yes { fill: var(--accent); }
.infographic-jsfor .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsfor .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsfor .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsfor .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsfor .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsfor .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsfor .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsfor .output strong { color: var(--ok); }
.infographic-jsfor .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsfor .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsfor *, .infographic-jsfor *::before, .infographic-jsfor *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The for Loop</h2>
<p class="ig-code">for (<strong>let i = 0</strong>; <strong>i < 5</strong>; <strong>i++</strong>) { print(i); }</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 600 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Condition -->
<g class="fc-edge" id="e-init-check">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="146">i < 5</text>
<text class="fc-text" x="365" y="160">?</text>
<text class="fc-mark" id="mark-check" x="400" y="115"></text>
</g>
<!-- Yes -> Statement -->
<g class="fc-edge" id="e-check-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="465" y="125" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="155">print(i)</text>
</g>
<!-- Statement -> Increment -->
<g class="fc-edge" id="e-statement-inc">
<path d="M525,125 L525,84"></path>
<polygon points="525,78 520,88 530,88"></polygon>
</g>
<!-- Increment -->
<g id="n-increment">
<rect class="fc-shape fc-block" x="465" y="25" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="55">i++</text>
</g>
<!-- Increment -> Condition (loop back) -->
<g class="fc-edge" id="e-inc-check">
<path d="M465,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsfor')
|| document.querySelector('.infographic-jsfor');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const MAX = 5;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nIncrement = wrapper.querySelector('#n-increment .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck = wrapper.querySelector('#e-init-check');
const eCheckYes = wrapper.querySelector('#e-check-yes');
const eStatementInc = wrapper.querySelector('#e-statement-inc');
const eIncCheck = wrapper.querySelector('#e-inc-check');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nCheck, nStatement, nIncrement, nEnd];
const allEdges = [eStartInit, eInitCheck, eCheckYes, eStatementInc, eIncCheck, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
// Build the full step sequence
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, i: 0, setBadge: 0 });
steps.push({ edge: eInitCheck });
for (let i = 0; i < MAX; i++) {
steps.push({ check: true, i, result: true });
steps.push({ edge: eCheckYes });
steps.push({ node: nStatement, i, print: i });
steps.push({ edge: eStatementInc });
steps.push({ node: nIncrement, i, setBadge: i + 1 });
steps.push({ edge: eIncCheck });
}
steps.push({ check: true, i: MAX, result: false });
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
buildSteps();
let idx = -1;
let timer = null;
let printed = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.print !== undefined) {
printed.push(step.print);
output.innerHTML = `output: <strong>${printed.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is now false.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, run the loop body`
: `i = ${step.i} β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
printed = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Example :
Loop to print numbers from 1 to 3
for (let i = 1; i <= 3; i++) {
console.log("Count:", i);
}Count: 1
Count: 2
Count: 3π Explanation:
Initializes the counter variable (let i = 1).
Tests the condition (i <= 3); runs while true.
Executes the loop body and increments the counter (i++).
β‘οΈ while Loop
The while loop executes as long as the condition is true. It can be thought of as a repeating if statement.
Syntax :
while (condition) {
// Code to execute
}<div class="infographic-jswhile">
<style>
.infographic-jswhile {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 700px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jswhile[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jswhile * { box-sizing: border-box; }
.infographic-jswhile .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jswhile .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jswhile .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jswhile .ig-code strong { color: var(--accent); }
.infographic-jswhile .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jswhile .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jswhile .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jswhile .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jswhile .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jswhile .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jswhile .stage svg { width: 100%; max-width: 580px; height: auto; overflow: visible; }
.infographic-jswhile .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jswhile .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jswhile .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jswhile .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jswhile .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jswhile .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jswhile .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jswhile .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jswhile .fc-text.on-block { font-weight: 700; }
.infographic-jswhile .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jswhile .fc-mark.yes { fill: var(--accent); }
.infographic-jswhile .fc-mark.no { fill: var(--ink-soft); }
.infographic-jswhile .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jswhile .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jswhile .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jswhile .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jswhile .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jswhile .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jswhile .output strong { color: var(--ok); }
.infographic-jswhile .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jswhile .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jswhile *, .infographic-jswhile *::before, .infographic-jswhile *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The while Loop</h2>
<p class="ig-code">let i = 0; while (<strong>i < 5</strong>) { print(i); <strong>i++</strong>; }</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 630 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Condition -->
<g class="fc-edge" id="e-init-check">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="146">i < 5</text>
<text class="fc-text" x="365" y="160">?</text>
<text class="fc-mark" id="mark-check" x="400" y="115"></text>
</g>
<!-- Yes -> Statement -->
<g class="fc-edge" id="e-check-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="465" y="125" width="150" height="50" rx="8"></rect>
<text class="fc-text on-block" x="540" y="146">print(i);</text>
<text class="fc-text on-block" x="540" y="163">i++;</text>
</g>
<!-- Statement -> Condition (loop back) -->
<g class="fc-edge" id="e-loop-back">
<path d="M540,125 L540,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jswhile')
|| document.querySelector('.infographic-jswhile');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const MAX = 5;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck = wrapper.querySelector('#e-init-check');
const eCheckYes = wrapper.querySelector('#e-check-yes');
const eLoopBack = wrapper.querySelector('#e-loop-back');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nCheck, nStatement, nEnd];
const allEdges = [eStartInit, eInitCheck, eCheckYes, eLoopBack, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 0 });
steps.push({ edge: eInitCheck });
for (let i = 0; i < MAX; i++) {
steps.push({ check: true, i, result: true });
steps.push({ edge: eCheckYes });
steps.push({ node: nStatement, i, print: i, setBadge: i + 1 });
steps.push({ edge: eLoopBack });
}
steps.push({ check: true, i: MAX, result: false });
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
buildSteps();
let idx = -1;
let timer = null;
let printed = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.print !== undefined) {
printed.push(step.print);
output.innerHTML = `output: <strong>${printed.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is now false.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, run the loop body`
: `i = ${step.i} β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
printed = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Example :
In this example, the code in the loop will run, over and over again, as long as a variable (i) is less than 10:
let i = 0;
let text = "";
while (i < 10) {
text += "The number is " + i + "\\n";
i++;
}
console.log(text);The nume is 0
The nume is 1
The nume is 2
The nume is 3
The nume is 4
The nume is 5
The nume is 6
The nume is 7
The nume is 8
The nume is 9βοΈ Explanation:
istarts at 0.The loop runs while
iis less than 10.On each loop, it adds
"The number is i"totextand increasesi.Once
ireaches 10, the loop stops.
π·οΈ do while Loop
The do while loop is a variant of the while loop. This loop will execute the code block once, before checking if the condition is true, then it will repeat the loop as long as the condition is true.
Syntax :
do {
*// code block to be executed*
}
while (*condition*);<div class="infographic-jsdowhile">
<style>
.infographic-jsdowhile {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 720px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsdowhile[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsdowhile * { box-sizing: border-box; }
.infographic-jsdowhile .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsdowhile .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsdowhile .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jsdowhile .ig-code strong { color: var(--accent); }
.infographic-jsdowhile .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsdowhile .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsdowhile .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsdowhile .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsdowhile .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsdowhile .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsdowhile .stage svg { width: 100%; max-width: 600px; height: auto; overflow: visible; }
.infographic-jsdowhile .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsdowhile .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsdowhile .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsdowhile .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsdowhile .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsdowhile .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsdowhile .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsdowhile .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsdowhile .fc-text.on-block { font-weight: 700; }
.infographic-jsdowhile .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsdowhile .fc-mark.yes { fill: var(--accent); }
.infographic-jsdowhile .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsdowhile .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsdowhile .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsdowhile .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsdowhile .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsdowhile .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsdowhile .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsdowhile .output strong { color: var(--ok); }
.infographic-jsdowhile .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsdowhile .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsdowhile *, .infographic-jsdowhile *::before, .infographic-jsdowhile *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The do...while Loop</h2>
<p class="ig-code">let i = 0; do { print(i); i++; } while (<strong>i < 5</strong>);</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 640 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Statement -->
<g class="fc-edge" id="e-init-statement">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Statement (runs first, before any check) -->
<g id="n-statement">
<rect class="fc-shape fc-block" x="315" y="125" width="150" height="50" rx="8"></rect>
<text class="fc-text on-block" x="390" y="146">print(i);</text>
<text class="fc-text on-block" x="390" y="163">i++;</text>
</g>
<!-- Statement -> Condition -->
<g class="fc-edge" id="e-statement-check">
<path d="M465,150 L479,150"></path>
<polygon points="485,150 475,145 475,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="555,95 625,150 555,205 485,150"></polygon>
<text class="fc-text" x="555" y="146">i < 5</text>
<text class="fc-text" x="555" y="160">?</text>
<text class="fc-mark" id="mark-check" x="590" y="115"></text>
</g>
<!-- Condition -> Statement (loop back, true) -->
<g class="fc-edge" id="e-loop-back">
<path d="M555,95 L555,50 L390,50 L390,84"></path>
<polygon points="390,90 385,80 395,80"></polygon>
</g>
<text class="edge-label" x="472" y="40">if true</text>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M555,205 L555,274"></path>
<polygon points="555,280 550,270 560,270"></polygon>
</g>
<text class="edge-label" x="571" y="240">if false</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="505" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="555" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsdowhile')
|| document.querySelector('.infographic-jsdowhile');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const MAX = 5;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitStatement = wrapper.querySelector('#e-init-statement');
const eStatementCheck = wrapper.querySelector('#e-statement-check');
const eLoopBack = wrapper.querySelector('#e-loop-back');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nStatement, nCheck, nEnd];
const allEdges = [eStartInit, eInitStatement, eStatementCheck, eLoopBack, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 0 });
steps.push({ edge: eInitStatement });
for (let i = 0; i < MAX; i++) {
steps.push({ node: nStatement, i, print: i, setBadge: i + 1 });
steps.push({ edge: eStatementCheck });
const nextI = i + 1;
const result = nextI < MAX;
steps.push({ check: true, i: nextI, result });
if (result) {
steps.push({ edge: eLoopBack });
} else {
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
}
}
buildSteps();
let idx = -1;
let timer = null;
let printed = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.print !== undefined) {
printed.push(step.print);
output.innerHTML = `output: <strong>${printed.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is now false.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, run the block again`
: `i = ${step.i} β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
printed = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Example :
let i = 0;
let text = "";
do {
text += "The number is " + i + "\\n";
i++;
} while (i < 10);
console.log(text);The nume is 0
The nume is 1
The nume is 2
The nume is 3
The nume is 4
The nume is 5
The nume is 6
The nume is 7
The nume is 8
The nume is 9In this example:
Executes the code block first.
Checks the condition (i < 10) after each iteration.
Why use do...while? Even if the condition is false on the first check, the loop runs once before checking.
β¦οΈ For In Loop
The JavaScript for in statement loops through the properties of an Object.
Syntax :
for (key in object) {
// *code block to be executed*
}<div class="infographic-jsforin">
<style>
.infographic-jsforin {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 700px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsforin[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsforin * { box-sizing: border-box; }
.infographic-jsforin .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsforin .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsforin .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.82rem; color: var(--ink-soft);
margin: 0 0 0.35rem;
}
.infographic-jsforin .ig-code strong { color: var(--accent); }
.infographic-jsforin .ig-obj {
text-align: center; font-family: var(--mono-font); font-size: 0.78rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jsforin .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsforin .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsforin .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsforin .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsforin .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsforin .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsforin .stage svg { width: 100%; max-width: 560px; height: auto; overflow: visible; }
.infographic-jsforin .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsforin .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsforin .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsforin .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsforin .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsforin .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsforin .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsforin .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsforin .fc-text.on-block { font-weight: 700; }
.infographic-jsforin .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsforin .fc-mark.yes { fill: var(--accent); }
.infographic-jsforin .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsforin .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsforin .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsforin .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsforin .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsforin .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsforin .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsforin .output strong { color: var(--ok); }
.infographic-jsforin .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsforin .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsforin *, .infographic-jsforin *::before, .infographic-jsforin *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The for...in Loop</h2>
<p class="ig-code">for (let x in person) { text += person[x] + " "; }</p>
<p class="ig-obj">person = { fname: "John", lname: "Doe", age: 25 }</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">x = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 600 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="146">keys of</text>
<text class="fc-text on-block" x="220" y="163">person</text>
</g>
<!-- Init -> Condition -->
<g class="fc-edge" id="e-init-check">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="141">keys</text>
<text class="fc-text" x="365" y="155">left ?</text>
<text class="fc-mark" id="mark-check" x="400" y="115"></text>
</g>
<!-- Yes -> Statement -->
<g class="fc-edge" id="e-check-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="465" y="125" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="146">text +=</text>
<text class="fc-text on-block" x="525" y="163">person[x]</text>
</g>
<!-- Statement -> Increment -->
<g class="fc-edge" id="e-statement-inc">
<path d="M525,125 L525,84"></path>
<polygon points="525,78 520,88 530,88"></polygon>
</g>
<!-- Increment (next key) -->
<g id="n-increment">
<rect class="fc-shape fc-block" x="465" y="25" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="55">next key</text>
</g>
<!-- Increment -> Condition (loop back) -->
<g class="fc-edge" id="e-inc-check">
<path d="M465,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsforin')
|| document.querySelector('.infographic-jsforin');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const person = { fname: "John", lname: "Doe", age: 25 };
const keys = Object.keys(person);
const MAX = keys.length;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nIncrement = wrapper.querySelector('#n-increment .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck = wrapper.querySelector('#e-init-check');
const eCheckYes = wrapper.querySelector('#e-check-yes');
const eStatementInc = wrapper.querySelector('#e-statement-inc');
const eIncCheck = wrapper.querySelector('#e-inc-check');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nCheck, nStatement, nIncrement, nEnd];
const allEdges = [eStartInit, eInitCheck, eCheckYes, eStatementInc, eIncCheck, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 'β' });
steps.push({ edge: eInitCheck });
for (let i = 0; i < MAX; i++) {
const key = keys[i];
steps.push({ check: true, remaining: MAX - i, result: true });
steps.push({ edge: eCheckYes });
steps.push({ node: nStatement, key, val: person[key], setBadge: key });
steps.push({ edge: eStatementInc });
steps.push({ node: nIncrement, advancing: true });
steps.push({ edge: eIncCheck });
}
steps.push({ check: true, remaining: 0, result: false });
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
buildSteps();
let idx = -1;
let timer = null;
let text = '';
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `x = "${step.setBadge}"`;
if (step.key !== undefined) {
text += step.val + ' ';
output.innerHTML = `text: <strong>"${text}"</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β no keys left.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
caption.textContent = step.result
? `${step.remaining} key(s) left β true, run the loop body`
: `no keys left β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
text = '';
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'x = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Example :
const person = { fname: "John", lname: "Doe", age: 25 };
let text = "";
for (let x in person) {
text += person[x] + " ";
}
console.log(text);Jhon Doe 25Explanation:
for (let x in person)loops through the keys:"fname","lname","age"person[x]gets the value for each key:person["fname"]β"John"person["lname"]β"Doe"person["age"]β25
So, all values are added to text as a single string.
ποΈ For Of Loop
The JavaScript
for ofstatement loops through the values of an iterable object.It lets you loop over iterable data structures such as Arrays, Strings, Maps, NodeLists, and more:
Syntax :
for (variable of iterable) {
// *code block to be executed*
}variable - For every iteration the value of the next property is assigned to the variable. Variable can be declared with
const,let, orvar.iterable - An object that has iterable properties.
<div class="infographic-jsforof">
<style>
.infographic-jsforof {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 700px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsforof[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsforof * { box-sizing: border-box; }
.infographic-jsforof .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsforof .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsforof .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.82rem; color: var(--ink-soft);
margin: 0 0 0.35rem;
}
.infographic-jsforof .ig-code strong { color: var(--accent); }
.infographic-jsforof .ig-obj {
text-align: center; font-family: var(--mono-font); font-size: 0.78rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jsforof .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsforof .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsforof .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsforof .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsforof .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsforof .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsforof .stage svg { width: 100%; max-width: 560px; height: auto; overflow: visible; }
.infographic-jsforof .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsforof .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsforof .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsforof .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsforof .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsforof .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsforof .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsforof .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsforof .fc-text.on-block { font-weight: 700; }
.infographic-jsforof .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsforof .fc-mark.yes { fill: var(--accent); }
.infographic-jsforof .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsforof .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsforof .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsforof .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsforof .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsforof .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsforof .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsforof .output strong { color: var(--ok); }
.infographic-jsforof .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsforof .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsforof *, .infographic-jsforof *::before, .infographic-jsforof *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The for...of Loop</h2>
<p class="ig-code">for (let val of a) { console.log(val); }</p>
<p class="ig-obj">a = [1, 2, 3, 4, 5]</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">val = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 600 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="146">values of</text>
<text class="fc-text on-block" x="220" y="163">a</text>
</g>
<!-- Init -> Condition -->
<g class="fc-edge" id="e-init-check">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="141">values</text>
<text class="fc-text" x="365" y="155">left ?</text>
<text class="fc-mark" id="mark-check" x="400" y="115"></text>
</g>
<!-- Yes -> Statement -->
<g class="fc-edge" id="e-check-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="465" y="125" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="155">log(val)</text>
</g>
<!-- Statement -> Increment -->
<g class="fc-edge" id="e-statement-inc">
<path d="M525,125 L525,84"></path>
<polygon points="525,78 520,88 530,88"></polygon>
</g>
<!-- Increment (next value) -->
<g id="n-increment">
<rect class="fc-shape fc-block" x="465" y="25" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="55">next value</text>
</g>
<!-- Increment -> Condition (loop back) -->
<g class="fc-edge" id="e-inc-check">
<path d="M465,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsforof')
|| document.querySelector('.infographic-jsforof');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const arr = [1, 2, 3, 4, 5];
const MAX = arr.length;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nIncrement = wrapper.querySelector('#n-increment .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck = wrapper.querySelector('#e-init-check');
const eCheckYes = wrapper.querySelector('#e-check-yes');
const eStatementInc = wrapper.querySelector('#e-statement-inc');
const eIncCheck = wrapper.querySelector('#e-inc-check');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nCheck, nStatement, nIncrement, nEnd];
const allEdges = [eStartInit, eInitCheck, eCheckYes, eStatementInc, eIncCheck, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 'β' });
steps.push({ edge: eInitCheck });
for (let i = 0; i < MAX; i++) {
const val = arr[i];
steps.push({ check: true, remaining: MAX - i, result: true });
steps.push({ edge: eCheckYes });
steps.push({ node: nStatement, val, log: val, setBadge: val });
steps.push({ edge: eStatementInc });
steps.push({ node: nIncrement, advancing: true });
steps.push({ edge: eIncCheck });
}
steps.push({ check: true, remaining: 0, result: false });
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
buildSteps();
let idx = -1;
let timer = null;
let logged = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `val = ${step.setBadge}`;
if (step.log !== undefined) {
logged.push(step.log);
output.innerHTML = `console: <strong>${logged.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β no values left.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
caption.textContent = step.result
? `${step.remaining} value(s) left β true, run the loop body`
: `no values left β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
logged = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'val = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Example :
let a = [1, 2, 3, 4, 5];
for (let val of a) {
console.log(val);
}1
2
3
4
5Explanation:
for...ofis used to loop through values of an iterable like an array.In each iteration,
valholds the current element of the arraya.
βΆοΈ Break and Continue
The
breakstatement "jumps out" of a loop.
βοΈ How does Break Work?
<div class="infographic-jsbreak">
<style>
.infographic-jsbreak {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--warn: #b45309;
--warn-soft: #fdf0dc;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 820px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsbreak[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
--warn: #e0a458;
--warn-soft: #3a2c14;
}
.infographic-jsbreak * { box-sizing: border-box; }
.infographic-jsbreak .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsbreak .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsbreak .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.8rem; color: var(--ink-soft);
margin: 0 0 1.75rem; line-height: 1.6;
}
.infographic-jsbreak .ig-code strong { color: var(--warn); }
.infographic-jsbreak .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsbreak .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsbreak .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsbreak .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsbreak .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsbreak .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsbreak .stage svg { width: 100%; max-width: 720px; height: auto; overflow: visible; }
.infographic-jsbreak .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsbreak .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsbreak .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsbreak .fc-shape.reached-break { fill: var(--warn-soft); stroke: var(--warn); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsbreak .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsbreak .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsbreak .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsbreak .fc-pill.reached-break { fill: var(--warn-soft); stroke: var(--warn); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsbreak .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsbreak .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsbreak .fc-text.on-block { font-weight: 700; }
.infographic-jsbreak .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsbreak .fc-mark.yes { fill: var(--accent); }
.infographic-jsbreak .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsbreak .fc-mark.break { fill: var(--warn); }
.infographic-jsbreak .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsbreak .edge-label.warn { fill: var(--warn); font-weight: 700; }
.infographic-jsbreak .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsbreak .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsbreak .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsbreak .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsbreak .fc-edge.is-break path { stroke: var(--warn); stroke-width: 2.5; }
.infographic-jsbreak .fc-edge.is-break polygon { fill: var(--warn); }
.infographic-jsbreak .junction { fill: var(--line); transition: fill 0.2s; }
.infographic-jsbreak .junction.is-active { fill: var(--accent); }
.infographic-jsbreak .junction.is-break { fill: var(--warn); }
.infographic-jsbreak .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsbreak .output strong { color: var(--ok); }
.infographic-jsbreak .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsbreak .caption strong { color: var(--ink); font-family: var(--mono-font); }
.infographic-jsbreak .caption strong.warn { color: var(--warn); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsbreak *, .infographic-jsbreak *::before, .infographic-jsbreak *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The break Statement</h2>
<p class="ig-code">for (let i = 1; i < 6; i++) {<br> if (i == 4) { <strong>break;</strong> }<br> console.log(i);<br>}</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 770 420" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 1</text>
</g>
<!-- Init -> Condition1 -->
<g class="fc-edge" id="e-init-check1">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition 1: i < 6 -->
<g id="n-check1">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="146">i < 6</text>
<text class="fc-text" x="365" y="160">?</text>
<text class="fc-mark" id="mark-check1" x="400" y="115"></text>
</g>
<!-- Yes1 -> Break check -->
<g class="fc-edge" id="e-check1-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<!-- Break check: i == 4 -->
<g id="n-breakcheck">
<polygon class="fc-shape" points="535,95 605,150 535,205 465,150"></polygon>
<text class="fc-text" x="535" y="146">i == 4</text>
<text class="fc-text" x="535" y="160">?</text>
<text class="fc-mark" id="mark-breakcheck" x="570" y="115"></text>
</g>
<!-- Break check No -> Statement -->
<g class="fc-edge" id="e-breakcheck-no">
<path d="M605,150 L629,150"></path>
<polygon points="635,150 625,145 625,155"></polygon>
</g>
<text class="edge-label" x="620" y="138">no</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="635" y="125" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="695" y="155">log(i)</text>
</g>
<!-- Statement -> Increment -->
<g class="fc-edge" id="e-statement-inc">
<path d="M695,125 L695,84"></path>
<polygon points="695,78 690,88 700,88"></polygon>
</g>
<!-- Increment -->
<g id="n-increment">
<rect class="fc-shape fc-block" x="635" y="25" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="695" y="55">i++</text>
</g>
<!-- Increment -> Condition1 (loop back) -->
<g class="fc-edge" id="e-inc-check1">
<path d="M635,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- Break check Yes -> down -> junction (break!) -->
<g class="fc-edge" id="e-breakcheck-yes">
<path d="M535,205 L535,290 L365,290"></path>
</g>
<text class="edge-label warn" x="551" y="240">yes β break!</text>
<!-- Condition1 No -> junction (loop finished normally) -->
<g class="fc-edge" id="e-check1-no">
<path d="M365,205 L365,284"></path>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- Junction -->
<circle class="junction" id="junction" cx="365" cy="290" r="4.5"></circle>
<!-- Junction -> End -->
<g class="fc-edge" id="e-junction-end">
<path d="M365,290 L365,334"></path>
<polygon points="365,340 360,330 370,330"></polygon>
</g>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="340" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="365">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsbreak')
|| document.querySelector('.infographic-jsbreak');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck1 = wrapper.querySelector('#n-check1 .fc-shape');
const markCheck1 = wrapper.querySelector('#mark-check1');
const nBreakCheck = wrapper.querySelector('#n-breakcheck .fc-shape');
const markBreakCheck = wrapper.querySelector('#mark-breakcheck');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nIncrement = wrapper.querySelector('#n-increment .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const junction = wrapper.querySelector('#junction');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck1 = wrapper.querySelector('#e-init-check1');
const eCheck1Yes = wrapper.querySelector('#e-check1-yes');
const eBreakcheckNo = wrapper.querySelector('#e-breakcheck-no');
const eStatementInc = wrapper.querySelector('#e-statement-inc');
const eIncCheck1 = wrapper.querySelector('#e-inc-check1');
const eBreakcheckYes = wrapper.querySelector('#e-breakcheck-yes');
const eCheck1No = wrapper.querySelector('#e-check1-no');
const eJunctionEnd = wrapper.querySelector('#e-junction-end');
const allNodes = [nStart, nInit, nCheck1, nBreakCheck, nStatement, nIncrement, nEnd];
const allEdges = [eStartInit, eInitCheck1, eCheck1Yes, eBreakcheckNo, eStatementInc, eIncCheck1, eBreakcheckYes, eCheck1No, eJunctionEnd];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no', 'reached-break'));
allEdges.forEach(e => e.classList.remove('is-active', 'is-break'));
junction.classList.remove('is-active', 'is-break');
markCheck1.textContent = ''; markCheck1.classList.remove('yes', 'no');
markBreakCheck.textContent = ''; markBreakCheck.classList.remove('yes', 'no', 'break');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 1 });
steps.push({ edge: eInitCheck1 });
let i = 1;
let safety = 0;
while (safety++ < 20) {
const cond1 = i < 6;
steps.push({ check1: true, i, result: cond1 });
if (!cond1) {
steps.push({ edge: eCheck1No });
steps.push({ junctionStep: true, viaBreak: false });
steps.push({ edge: eJunctionEnd });
steps.push({ node: nEnd, done: true });
break;
}
steps.push({ edge: eCheck1Yes });
const isBreak = (i === 4);
steps.push({ breakcheck: true, i, result: isBreak });
if (isBreak) {
steps.push({ edge: eBreakcheckYes });
steps.push({ junctionStep: true, viaBreak: true });
steps.push({ edge: eJunctionEnd });
steps.push({ node: nEnd, done: true, viaBreak: true });
break;
}
steps.push({ edge: eBreakcheckNo });
steps.push({ node: nStatement, i, log: i });
steps.push({ edge: eStatementInc });
steps.push({ node: nIncrement, setBadge: i + 1 });
steps.push({ edge: eIncCheck1 });
i++;
}
}
buildSteps();
let idx = -1;
let timer = null;
let logged = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add(step.edge === eBreakcheckYes || (step.edge === eJunctionEnd && wasBreak) ? 'is-break' : 'is-active');
}
if (step.junctionStep) {
junction.classList.add(step.viaBreak ? 'is-break' : 'is-active');
wasBreak = step.viaBreak;
}
if (step.node) {
step.node.classList.add(step.viaBreak ? 'reached-break' : 'reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.log !== undefined) {
logged.push(step.log);
output.innerHTML = `console: <strong>${logged.join(', ')}</strong>`;
}
if (step.done) {
caption.innerHTML = step.viaBreak
? `loop exited early via <strong class="warn">break</strong>`
: `loop finished normally β condition is false`;
}
}
if (step.check1) {
nCheck1.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck1.textContent = step.result ? 'β' : 'β';
markCheck1.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
if (!step.result) caption.textContent = `i = ${step.i} β false, exit the loop`;
else caption.textContent = `i = ${step.i} β true, check for break`;
}
if (step.breakcheck) {
nBreakCheck.classList.add(step.result ? 'reached-break' : 'reached-no');
markBreakCheck.textContent = step.result ? 'β' : 'β';
markBreakCheck.classList.add(step.result ? 'break' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.innerHTML = step.result
? `i = ${step.i} β <strong class="warn">break!</strong> exit loop immediately`
: `i = ${step.i} β not 4, keep going`;
}
}
let wasBreak = false;
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
logged = [];
wasBreak = false;
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});Example :
for (let i = 1; i < 6; i++) {
if (i == 4) {
break;
}
console.log(i);
}1
2
3π΄ Explanation:
The loop starts at
i = 1and continues whilei < 6When
i == 4, thebreakstatement is triggered, and the loop stops immediatelySo it prints only
1,2, and3
The
continuestatement "jumps over" one iteration in the loop.
βοΈ How Does Continue Work?
<div class="infographic-jscontinue">
<style>
.infographic-jscontinue {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--warn: #b45309;
--warn-soft: #fdf0dc;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 820px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jscontinue[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
--warn: #e0a458;
--warn-soft: #3a2c14;
}
.infographic-jscontinue * { box-sizing: border-box; }
.infographic-jscontinue .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jscontinue .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jscontinue .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.8rem; color: var(--ink-soft);
margin: 0 0 1.75rem; line-height: 1.6;
}
.infographic-jscontinue .ig-code strong { color: var(--warn); }
.infographic-jscontinue .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jscontinue .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jscontinue .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jscontinue .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jscontinue .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jscontinue .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jscontinue .stage svg { width: 100%; max-width: 720px; height: auto; overflow: visible; }
.infographic-jscontinue .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jscontinue .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jscontinue .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jscontinue .fc-shape.reached-skip { fill: var(--warn-soft); stroke: var(--warn); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jscontinue .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jscontinue .fc-block.reached-skip { fill: var(--warn-soft); stroke: var(--warn); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jscontinue .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jscontinue .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jscontinue .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jscontinue .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jscontinue .fc-text.on-block { font-weight: 700; }
.infographic-jscontinue .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jscontinue .fc-mark.yes { fill: var(--accent); }
.infographic-jscontinue .fc-mark.no { fill: var(--ink-soft); }
.infographic-jscontinue .fc-mark.skip { fill: var(--warn); }
.infographic-jscontinue .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jscontinue .edge-label.warn { fill: var(--warn); font-weight: 700; }
.infographic-jscontinue .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jscontinue .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jscontinue .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jscontinue .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jscontinue .fc-edge.is-skip path { stroke: var(--warn); stroke-width: 2.5; }
.infographic-jscontinue .fc-edge.is-skip polygon { fill: var(--warn); }
.infographic-jscontinue .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jscontinue .output strong { color: var(--ok); }
.infographic-jscontinue .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jscontinue .caption strong { color: var(--ink); font-family: var(--mono-font); }
.infographic-jscontinue .caption strong.warn { color: var(--warn); }
@media (prefers-reduced-motion: reduce) {
.infographic-jscontinue *, .infographic-jscontinue *::before, .infographic-jscontinue *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The continue Statement</h2>
<p class="ig-code">for (let i = 0; i < 10; i++) {<br> if (i % 2 == 0) { <strong>continue;</strong> }<br> console.log(i);<br>}</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 770 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Condition1 -->
<g class="fc-edge" id="e-init-check1">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition 1: i < 10 -->
<g id="n-check1">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="146">i < 10</text>
<text class="fc-text" x="365" y="160">?</text>
<text class="fc-mark" id="mark-check1" x="400" y="115"></text>
</g>
<!-- Yes1 -> Continue check -->
<g class="fc-edge" id="e-check1-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<!-- Continue check: i % 2 == 0 -->
<g id="n-continuecheck">
<polygon class="fc-shape" points="535,95 605,150 535,205 465,150"></polygon>
<text class="fc-text" x="535" y="141">i % 2</text>
<text class="fc-text" x="535" y="155">== 0 ?</text>
<text class="fc-mark" id="mark-continuecheck" x="570" y="115"></text>
</g>
<!-- Continue check No (odd) -> Statement -->
<g class="fc-edge" id="e-cc-no">
<path d="M605,150 L629,150"></path>
<polygon points="635,150 625,145 625,155"></polygon>
</g>
<text class="edge-label" x="620" y="138">no</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="635" y="125" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="695" y="155">log(i)</text>
</g>
<!-- Statement -> Increment -->
<g class="fc-edge" id="e-statement-inc">
<path d="M695,125 L695,84"></path>
<polygon points="695,78 690,88 700,88"></polygon>
</g>
<!-- Increment -->
<g id="n-increment">
<rect class="fc-shape fc-block" x="635" y="25" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="695" y="55">i++</text>
</g>
<!-- Continue check Yes (even) -> down and back to Condition1, skipping Statement/Increment display -->
<g class="fc-edge" id="e-cc-yes">
<path d="M535,205 L535,245 L365,245 L365,211"></path>
<polygon points="365,205 360,211 370,211"></polygon>
</g>
<text class="edge-label warn" x="450" y="260">yes β continue!</text>
<!-- Increment -> Condition1 (loop back) -->
<g class="fc-edge" id="e-inc-check1">
<path d="M635,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- Condition1 No -> End -->
<g class="fc-edge" id="e-check1-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jscontinue')
|| document.querySelector('.infographic-jscontinue');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck1 = wrapper.querySelector('#n-check1 .fc-shape');
const markCheck1 = wrapper.querySelector('#mark-check1');
const nContinueCheck = wrapper.querySelector('#n-continuecheck .fc-shape');
const markContinueCheck = wrapper.querySelector('#mark-continuecheck');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nIncrement = wrapper.querySelector('#n-increment .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck1 = wrapper.querySelector('#e-init-check1');
const eCheck1Yes = wrapper.querySelector('#e-check1-yes');
const eCcNo = wrapper.querySelector('#e-cc-no');
const eStatementInc = wrapper.querySelector('#e-statement-inc');
const eIncCheck1 = wrapper.querySelector('#e-inc-check1');
const eCcYes = wrapper.querySelector('#e-cc-yes');
const eCheck1No = wrapper.querySelector('#e-check1-no');
const allNodes = [nStart, nInit, nCheck1, nContinueCheck, nStatement, nIncrement, nEnd];
const allEdges = [eStartInit, eInitCheck1, eCheck1Yes, eCcNo, eStatementInc, eIncCheck1, eCcYes, eCheck1No];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no', 'reached-skip'));
allEdges.forEach(e => e.classList.remove('is-active', 'is-skip'));
markCheck1.textContent = ''; markCheck1.classList.remove('yes', 'no');
markContinueCheck.textContent = ''; markContinueCheck.classList.remove('yes', 'no', 'skip');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 0 });
steps.push({ edge: eInitCheck1 });
let i = 0;
let safety = 0;
while (safety++ < 40) {
const cond1 = i < 10;
steps.push({ check1: true, i, result: cond1 });
if (!cond1) {
steps.push({ edge: eCheck1No });
steps.push({ node: nEnd, done: true });
break;
}
steps.push({ edge: eCheck1Yes });
const isEven = (i % 2 === 0);
steps.push({ ccheck: true, i, result: isEven });
if (isEven) {
steps.push({ edge: eCcYes, skip: true });
} else {
steps.push({ edge: eCcNo });
steps.push({ node: nStatement, i, log: i });
steps.push({ edge: eStatementInc });
steps.push({ node: nIncrement, setBadge: i + 1 });
steps.push({ edge: eIncCheck1 });
}
i++;
}
}
buildSteps();
let idx = -1;
let timer = null;
let logged = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add(step.skip ? 'is-skip' : 'is-active');
}
if (step.node) {
if (step.skip) {
step.node.classList.add('reached-skip');
} else {
step.node.classList.add('reached');
}
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.log !== undefined) {
logged.push(step.log);
output.innerHTML = `console: <strong>${logged.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is false.';
}
}
if (step.check1) {
nCheck1.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck1.textContent = step.result ? 'β' : 'β';
markCheck1.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, check for even`
: `i = ${step.i} β false, exit the loop`;
}
if (step.ccheck) {
nContinueCheck.classList.add(step.result ? 'reached-skip' : 'reached-no');
markContinueCheck.textContent = step.result ? 'β' : 'β';
markContinueCheck.classList.add(step.result ? 'skip' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.innerHTML = step.result
? `i = ${step.i} β even, <strong class="warn">continue!</strong> jump back to the condition`
: `i = ${step.i} β odd, log it`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 700);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
logged = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});If continue is used in a for loop, the control flow jumps to the test expression after skipping the current iteration.
Example :
Continue to print only odd Numbers smaller than 10
for (let i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue;
}
console.log(i);
}1
3
5
7
9π Explanation:
The loop runs from
i = 0toi < 10i % 2 == 0checks ifiis evenIf
iis even,continueskips that iterationSo only odd numbers (
1, 3, 5, 7, 9) are printed
π Continue vs Break
The major difference between the continue and break statement is that the break statement breaks out of the loop completely while continue is used to break one statement and iterate to the next statement.