Skip to content

Instantly share code, notes, and snippets.

@devendran-m
Last active September 18, 2025 07:21
Show Gist options
  • Select an option

  • Save devendran-m/16a625f6029e213b3c214e080701c7cf to your computer and use it in GitHub Desktop.

Select an option

Save devendran-m/16a625f6029e213b3c214e080701c7cf to your computer and use it in GitHub Desktop.
JavaScript Execution Context Visualization
function map(array, callback) {
const newArray = [];
for (let i = 0; i < array.length; i++ ) {
console.log("array[i], newArray[i]", array[i], newArray[i]);
newArray.push(callback(array[i]));
}
return newArray;
}
const multiplyByTwo = (num) => num * 2;
//console.log(map([1, 2, 3], addTwo));
console.log(map([1, 2, 3], multiplyByTwo));
console.log(multiplyByTwo(1));
console.log(multiplyByTwo(2));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Execution Step-by-Step</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 15px;
padding: 30px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
}
.header {
text-align: center;
margin-bottom: 30px;
}
.header h1 {
color: #2c3e50;
font-size: 2.5em;
margin-bottom: 10px;
}
.controls {
text-align: center;
margin-bottom: 30px;
}
.btn {
background: linear-gradient(45deg, #3498db, #2980b9);
color: white;
border: none;
padding: 12px 24px;
margin: 0 10px;
border-radius: 25px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s ease;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4);
}
.btn:disabled {
background: #bdc3c7;
cursor: not-allowed;
transform: none;
}
.execution-display {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
margin-bottom: 30px;
}
.panel {
background: #f8f9fa;
border-radius: 10px;
padding: 20px;
border: 2px solid #e9ecef;
}
.panel h3 {
color: #2c3e50;
margin-top: 0;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
}
.call-stack {
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
}
.global-memory {
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
}
.local-memory {
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
}
.stack-frame {
background: white;
padding: 10px;
margin: 5px 0;
border-radius: 5px;
border-left: 4px solid #e74c3c;
font-family: 'Courier New', monospace;
}
.memory-item {
background: white;
padding: 8px;
margin: 3px 0;
border-radius: 5px;
font-family: 'Courier New', monospace;
font-size: 14px;
}
.current-step {
background: #fff3cd;
border: 2px solid #ffc107;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
}
.step-counter {
background: #007bff;
color: white;
padding: 5px 15px;
border-radius: 20px;
display: inline-block;
margin-bottom: 10px;
font-weight: bold;
}
.code-highlight {
background: #f8f9fa;
border-left: 4px solid #28a745;
padding: 15px;
font-family: 'Courier New', monospace;
margin: 10px 0;
border-radius: 5px;
}
.output-section {
background: #2c3e50;
color: #ecf0f1;
padding: 20px;
border-radius: 10px;
font-family: 'Courier New', monospace;
}
.output-line {
margin: 5px 0;
padding: 5px;
background: rgba(255,255,255,0.1);
border-radius: 3px;
}
.highlight {
background: #f1c40f !important;
color: #2c3e50 !important;
font-weight: bold;
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🚀 JavaScript Execution Visualization</h1>
<p>Step-by-step execution of your callback function program</p>
</div>
<div class="controls">
<button class="btn" id="prevBtn" onclick="previousStep()">⬅️ Previous</button>
<button class="btn" id="nextBtn" onclick="nextStep()">Next ➡️</button>
<button class="btn" onclick="resetExecution()">🔄 Reset</button>
<button class="btn" onclick="autoPlay()">▶️ Auto Play</button>
</div>
<div class="current-step fade-in" id="currentStep">
<div class="step-counter" id="stepCounter">Step 1 of 15</div>
<div id="stepDescription">Program starts - Global Execution Context is created</div>
</div>
<div class="execution-display">
<div class="panel call-stack">
<h3>📚 Call Stack</h3>
<div id="callStack">
<div class="stack-frame">Global Execution Context</div>
</div>
</div>
<div class="panel global-memory">
<h3>🌍 Global Memory</h3>
<div id="globalMemory">
<div class="memory-item">map: function</div>
<div class="memory-item">multiplyByTwo: function</div>
</div>
</div>
<div class="panel local-memory">
<h3>🏠 Local Memory</h3>
<div id="localMemory">
<div class="memory-item">None yet</div>
</div>
</div>
</div>
<div class="output-section">
<h3>📤 Console Output:</h3>
<div id="consoleOutput">
<div class="output-line" style="opacity: 0.5;">Waiting for execution...</div>
</div>
</div>
</div>
<script>
let currentStepIndex = 0;
let isAutoPlaying = false;
const executionSteps = [
{
step: 1,
description: "Program starts - Global Execution Context is created and pushed to Call Stack",
callStack: ["Global Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["None"],
output: []
},
{
step: 2,
description: "Function declarations are hoisted and stored in Global Memory",
callStack: ["Global Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["None"],
output: []
},
{
step: 3,
description: "Executing: console.log(map([1, 2, 3], multiplyByTwo))",
callStack: ["Global Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["None"],
output: []
},
{
step: 4,
description: "Function call: map([1, 2, 3], multiplyByTwo) - New Execution Context created",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: []", "i: undefined"],
output: []
},
{
step: 5,
description: "Inside map(): newArray = [], i = 0, entering for loop",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: []", "i: 0"],
output: []
},
{
step: 6,
description: "First iteration: console.log shows array[0]=1, newArray[0]=undefined",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: []", "i: 0"],
output: ["array[i], newArray[i] 1 undefined"]
},
{
step: 7,
description: "Calling callback(array[0]) = multiplyByTwo(1) - New Execution Context",
callStack: ["Global Execution Context", "map() Execution Context", "multiplyByTwo() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["num: 1"],
output: ["array[i], newArray[i] 1 undefined"]
},
{
step: 8,
description: "multiplyByTwo returns 2, pushing to newArray. i increments to 1",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: [2]", "i: 1"],
output: ["array[i], newArray[i] 1 undefined"]
},
{
step: 9,
description: "Second iteration: console.log shows array[1]=2, newArray[1]=undefined",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: [2]", "i: 1"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined"]
},
{
step: 10,
description: "Calling multiplyByTwo(2) - returns 4, pushing to newArray",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: [2, 4]", "i: 2"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined"]
},
{
step: 11,
description: "Third iteration: console.log shows array[2]=3, newArray[2]=undefined",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: [2, 4]", "i: 2"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined", "array[i], newArray[i] 3 undefined"]
},
{
step: 12,
description: "Calling multiplyByTwo(3) - returns 6, pushing to newArray. Loop ends",
callStack: ["Global Execution Context", "map() Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["array: [1, 2, 3]", "callback: multiplyByTwo", "newArray: [2, 4, 6]", "i: 3"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined", "array[i], newArray[i] 3 undefined"]
},
{
step: 13,
description: "map() returns [2, 4, 6]. Execution Context popped. console.log prints result",
callStack: ["Global Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["None"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined", "array[i], newArray[i] 3 undefined", "[ 2, 4, 6 ]"]
},
{
step: 14,
description: "Executing: console.log(multiplyByTwo(1)) - prints 2",
callStack: ["Global Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["None"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined", "array[i], newArray[i] 3 undefined", "[ 2, 4, 6 ]", "2"]
},
{
step: 15,
description: "Executing: console.log(multiplyByTwo(2)) - prints 4. Program complete!",
callStack: ["Global Execution Context"],
globalMemory: ["map: function", "multiplyByTwo: function"],
localMemory: ["None"],
output: ["array[i], newArray[i] 1 undefined", "array[i], newArray[i] 2 undefined", "array[i], newArray[i] 3 undefined", "[ 2, 4, 6 ]", "2", "4"]
}
];
function updateDisplay() {
const step = executionSteps[currentStepIndex];
// Update step counter and description
document.getElementById('stepCounter').textContent = `Step ${step.step} of ${executionSteps.length}`;
document.getElementById('stepDescription').textContent = step.description;
// Update call stack
const callStackDiv = document.getElementById('callStack');
callStackDiv.innerHTML = '';
step.callStack.forEach((frame, index) => {
const div = document.createElement('div');
div.className = 'stack-frame';
if (index === step.callStack.length - 1 && step.callStack.length > 1) {
div.classList.add('highlight');
}
div.textContent = frame;
callStackDiv.appendChild(div);
});
// Update global memory
const globalMemoryDiv = document.getElementById('globalMemory');
globalMemoryDiv.innerHTML = '';
step.globalMemory.forEach(item => {
const div = document.createElement('div');
div.className = 'memory-item';
div.textContent = item;
globalMemoryDiv.appendChild(div);
});
// Update local memory
const localMemoryDiv = document.getElementById('localMemory');
localMemoryDiv.innerHTML = '';
step.localMemory.forEach(item => {
const div = document.createElement('div');
div.className = 'memory-item';
div.textContent = item;
localMemoryDiv.appendChild(div);
});
// Update console output
const outputDiv = document.getElementById('consoleOutput');
outputDiv.innerHTML = '';
if (step.output.length === 0) {
outputDiv.innerHTML = '<div class="output-line" style="opacity: 0.5;">No output yet...</div>';
} else {
step.output.forEach((line, index) => {
const div = document.createElement('div');
div.className = 'output-line';
if (index === step.output.length - 1 && currentStepIndex > 5) {
div.classList.add('highlight');
}
div.textContent = line;
outputDiv.appendChild(div);
});
}
// Update button states
document.getElementById('prevBtn').disabled = currentStepIndex === 0;
document.getElementById('nextBtn').disabled = currentStepIndex === executionSteps.length - 1;
// Add fade-in animation
document.getElementById('currentStep').classList.remove('fade-in');
setTimeout(() => {
document.getElementById('currentStep').classList.add('fade-in');
}, 10);
}
function nextStep() {
if (currentStepIndex < executionSteps.length - 1) {
currentStepIndex++;
updateDisplay();
}
}
function previousStep() {
if (currentStepIndex > 0) {
currentStepIndex--;
updateDisplay();
}
}
function resetExecution() {
currentStepIndex = 0;
isAutoPlaying = false;
updateDisplay();
}
function autoPlay() {
if (isAutoPlaying) return;
isAutoPlaying = true;
const interval = setInterval(() => {
if (currentStepIndex < executionSteps.length - 1) {
nextStep();
} else {
isAutoPlaying = false;
clearInterval(interval);
}
}, 2000);
}
// Initialize display
updateDisplay();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment