A Perplexing JavaScript Parsing Puzzle
14 comments
·March 12, 2025gitpusher
I don't understand. The prompt is given as 4 lines:
x
= 1
x
--> 0
which does not execute. And if I run them as two lines:
x = 1
x --> 0
then the final output is `true`. `1` is only output during the initial assignment, which is hardly surprising
If i understand correctly, the reason i am getting `true` is because the second line gets parsed as two operations:
(x--) > 0
first a post-decrement operator (--) followed by a comparison (greater than). Since x = 1 it's greater than 0 (true), but afterward it's decremented so you'll get false if you run the same line again
ddalcino
You can also use “shift + enter” to add a newline to your input, without telling the browser to take your input yet.
IainIreland
Copy and paste all four lines at once.
gitpusher
Oops, haha. Yes now i am getting `1` as the result. Thanks for the tip.
throwanem
I forgot you could use SGML comments in JS in 1995, so read it as a postdecrement and inequality returning true. Don't feel too bad about that here 30 years on, if I'm honest.
binarymax
I'm trying to remember exactly when I stopped inlining js with html comments in the script tag. Maybe it was when IE6 got its foothold?
indentit
The syntax highlighting on the code snippet is highly misleading...
TRiG_Ireland
The history of the web gives us so many odd wrinkles.
sroussey
class John { constructor(){console.log("Nope")} }
John.constructor("alert('hello')")()
JS has been around a long time. Lots of old stuff hangs around.
Yes, it pops an alert, and no it does not console log.
eyelidlessness
For folks wondering why: this is because a class is (approximately) syntactic sugar for defining a constructor function, and the constructor of a function is `Function`, and calling `Function(string)` is an implicit eval.
gowld
Why doesn't it call the console.log() ?
eyelidlessness
Because both of these are true:
John.constructor === Function
John !== Function
John is (approximately) a reference to a desugaring of its `constructor` “method” (which is the term I see used on MDN, I would have expected something more akin to “constructor declaration”; not 100% sure what the spec terminology is and don’t have time to chase it down atm) + its instance members assigned to the desugared function’s prototype. It’s more complicated than that for… reasons.But the gist is that John.constructor references something other than the constructor defined in the class body, so calling that reference doesn’t call the thing it doesn’t reference at all.
cess11
Fun wart. Been a couple of decades or so since I last wrapped <script> contents like that but not long enough that I didn't have a correct suspicion about the execution result.
here I was thinking about operator precedence and semicolon insertion and it was something entirely unexpected.