Curious JavaScript Quirks Found Rewriting 'Hello, World'
• ~300 words • 1 minute read
I have a silly project on GitHub right now called 101 Hello Worlds. The goal is to come up with 101 unique and convoluted ways to write a function that returns a simple string: Hello, World. It's fun, in the spirit of code golfing and requires you to think outside the box.
Over the course of creating and reviewing submissions for the project I've come across a couple curious JavaScript quirks worth sharing:
Requiring Modules Inside Evals Invoked by Reference
During a recent pairing session with a fellow Recurse Center attendee we stumbled across an odd bit of JavaScript behvior: if you try to eval
a require
statement it will only work if eval
is called directly and will fail if it's invoked by reference.
What does that mean in plain English? It's probably easier to show in code.
This should work:
eval("require('./module.js')")
This should not work:
const e = eval;
e("require('./module.js')")
You will get the error message require is not defined
, which is probably a first if you were like us.
Why is that? The description over at Mozilla Developer Network says evals invoked by reference will work in the "global" scope instead of the "local" scope. I guess that makes require
unavailable to it in this context, for whatever reason.
Adding to the confusion, when I try these exact same examples from the Node.js REPL both approaches work for me.
Obligatory warning: Never use eval()!.
Tagged Template Strings
Not to be confused with your run-of-the-mill template literals, which I use quite often and find very useful.
Did you know you can do this?
console.log`wtf`
That's not a typo. You're probably used to seeing it formatted more like this:
console.log(`wtf`)
Wes Bos has a nice explanation about tagged template strings that actually makes sense and even provides a use-case for why you might want them.