Scary JavaScript on Friday the 13th


[Dark, smoky room lit only by the ethereal glow of a green monochrome display. A hooded figure with a long, gray beard appears, wisps of smoke floating around. The scene feels like it's from ancient times, yet also with a hint of 1980s computer labs.]
The First Programmer (in a haunting voice): "Ah, young developers! Gather around, for tonight, on this Friday the 13th, you shall hear the chilling tale of the birth of JavaScript—the language that binds our realm with the spooky Other World of Javascript."
[Thunderclaps in the distance.]
Long ago, when code was written on sacred parchment and debugging involved literal bugs, the Other World of Javascript was a mysterious realm. This realm, draped in darkness, was ruled by the haunting specter named Null and his sinister cohort, Undefined.
One fateful Friday the 13th, a curious programmer from our realm sought power beyond imagination. Using an ancient Node.js ritual, they conjured a bridge between our world and the Other World of Javascript.
As the bridge materialized, eerie events began to unfold. Variables started acting bizarrely, shifting between types as if possessed! Strings and numbers combined in unpredictable ways, giving birth to NaN—the infamous Not-a-Number demon. And, lurking in the shadows, callbacks from the abyss waited, ensuring that tasks would NEVER complete in the order you'd expect.
But with darkness, came light. From the depths of the Other World, the ancient spell of 'Async-Await' was discovered, granting programmers the power to harness the chaotic energy. Yet, with great power came greater responsibilities. Errors were thrown, and only those who dared to catch them could prevent the apocalypse of endless loops and system crashes.
The First Programmer (with a wink): "And thus, my students, on each Friday the 13th, it is your sacred duty to embark on a hackathon, mastering the ancient arts of Node.js and JavaScript. You must be ready, for bugs from the Other World lurk in every corner, waiting to test your skills. Your weapons are your logic, your wit, and a solid grasp of the asynchronous magic."
"But fear not, for while the Other World of Javascript may be shrouded in mystery and horror, it is also filled with wonders and opportunities. With the right incantations, methods, and a little bit of callback magic, you can harness its power to build wondrous applications and solutions."
[The room starts fading back into darkness, with the First Programmer slowly disappearing into the mist.]
The First Programmer (fading away): "Now, go forth, my students! Dive deep into the code, conquer the challenges, and may your functions always return without error! Beware of the NaNs, embrace the mysteries of the Other World, and may your code be ever... bug-free!"
[Scene ends with a ghostly chuckle.]

Let's start with the terrifying tales of the Temporal Dead Zone (TDZ). The TDZ is the period where variables declared using let and const are unaccessible, even though their respective scopes have started. Accessing these variables before their actual declaration will result in a frightening ReferenceError.

Epoch 1: The Stirring of the Portal
Escape the Temporal Dead Zone
The temporal dead zone (TDZ) is a behavior that occurs in JavaScript when trying to access variables declared with the `let` or `const` keywords before they have been initialized. The TDZ ensures that variables are not accessed before they have been assigned a value, preventing potential bugs.
In JavaScript, variable declarations with `let` and `const` are hoisted to the top of their respective scope, but unlike variables declared with `var`, they are not initialized with a default value of `undefined`.
Instead, they remain uninitialized until their declaration statement is reached during the runtime's execution.
If you attempt to access a variable within its TDZ, a `ReferenceError` will be thrown.
This means that the variable exists in the scope but is not yet ready to be accessed.
The TDZ ends as soon as the variable's initialization statement is encountered.
Here's an example to illustrate the TDZ in JavaScript:```javascript console.log(x); // ReferenceError: x is not definedlet x = 10; // Variable declaration (hoisted) but still in TDZconsole.log(x); // 10 ```In the example above, trying to access the variable `x` before its declaration statement results in a `ReferenceError`. Once the declaration statement is encountered, the variable `x` is initialized and can be accessed without any issues.
It's important to be aware of the TDZ when using `let` and `const`, and ensure that variables are appropriately initialized before attempting to access them in your code. // Try accessing a variable before it's declared to witness the horror of the TDZ. function temporalDeadZone() { try { console.log(scaryVariable); // This should throw an error
let scaryVariable = "Safe now!"; } catch (error) { console.log("Beware! You've entered the Temporal Dead Zone!", error.message); } } temporalDeadZone();
Prevent NaN Summoning
javascriptCopy code
function safeAddition(a, b) { if (typeof a === 'number' && typeof b === 'number') { console.log(a + b); } else { console.log("Warning! Adding non-numbers can summon NaN demons!"); } } safeAddition(5, "13"); // Warning!
Close the Variable Leak
javascriptCopy codeif (true)
{ let safeZone = "Portal is safe!"; }
try { console.log(safeZone); // This should throw an error since safeZone is out of scope here } catch (error) {
console.log("Safe Zone remains protected. The portal is contained!", error.message); } /////
The variable safeZone is block-scoped due to the use of let, which means it's only accessible within the block where it was declared,
in this case within the {} of the if statement.
That's why when you try to access safeZone outside of the block, it will throw a reference error.
The provided code demonstrates this behavior and seems correct as per the intention to show that safeZone is out of scope and throw an error.
However, for better readability and clarity, I'd recommend formatting the code as follows:
javascriptCopy code
if (true) { let safeZone = "Portal is safe!"; }
try { console.log(safeZone); // This will throw an error since safeZone is out of scope here } catch (error) { console.log("Safe Zone remains protected. The portal is contained!", error.message); }
This more readable format still exhibits the same behavior: attempting to log the value of safeZone will throw a ReferenceError which will be caught and handled in the catch block.
Exorcise the Undefined Demon
javascriptCopy codefunction checkVariable(variable) { if (typeof variable === 'undefined') { console.log("Warning! Undefined demon detected!"); } else { console.log("All is well:", variable); } } checkVariable(); // Warning!
Epoch 2: The Portal Widens
Purge the Callback Horrors
javascriptCopy codefunction randomDelay(callback) { setTimeout(callback, Math.random() * 2000 + 1000); } randomDelay(() => { console.log("Portal Closed!"); });
Chain the Promised Beasts

function randomDelayPromise() { return new Promise((resolve) => { setTimeout(() => { resolve("Promise Beasts Chained!"); }, Math.random() * 2000 + 1000); }); } randomDelayPromise().then(message => console.log(message));
Remember students, while the world of JavaScript may have its terrifying zones, with the right spells (and syntax), you can ward off any eerie error and create magic! Now, continue coding and don't let the callbacks bite! 🕸🔮🎃

Epoch 3: Shadows Over the Asynchronous Abyss

Battle the Asynchronous Demons with Async/Await
javascriptCopy code
// Convert the randomDelayPromise function to an async function and await its result. async function battleAsyncDemons() { try { let message = await randomDelayPromise(); console.log(message); } catch (error) { console.log("The Async Demons are upon us!", error.message); } } battleAsyncDemons();
Vanquish the Phantom this
javascriptCopy code
// Inside the ghost object, bind the scream method to always use ghost as its context. const ghost = { name: 'Phantom', scream: function() { console.log(`${} says BOO!`); } }; const stolenScream = ghost.scream; stolenScream(); // This should log "undefined says BOO!" const boundScream = stolenScream.bind(ghost); boundScream(); // This should log "Phantom says BOO!"
Unravel the Event Loop Mystery
javascriptCopy code
// Unravel the order of console logs in the Event Loop. console.log("A ghostly figure appears..."); setTimeout(() => { console.log("The ghost vanishes after a delay..."); }, 0); Promise.resolve().then(() => console.log("The ghost left a trace in the promise world!")); console.log("End of the haunted script."); // What's the order of the logs?
Epoch 4: The Final Confrontation
Escape the Callback Hell
javascriptCopy code// Refactor this callback mess into a neat async/await sequence.
function getData(callback) { setTimeout(() => { callback({ data: "Spooky data" }); }, 1000);}
function processData(data, callback) { setTimeout(() => { callback(data + " processed!"); }, 1000);}
getData((data) => { processData(, (processed) => { console.log(processed); // Should print "Spooky data processed!" });});
// Refactor above here
Defend Against the Zombie null Checks
javascriptCopy code// Protect the function from null or undefined inputs using optional chaining.
function checkZombieProperty(obj) { console.log(obj?.zombie?.scream ?? "Safe, for now...");}
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
) instead.