Last active
September 18, 2025 07:21
-
-
Save devendran-m/16a625f6029e213b3c214e080701c7cf to your computer and use it in GitHub Desktop.
JavaScript Execution Context Visualization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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