Skip to content(if available)orjump to list(if available)

A Perplexing JavaScript Parsing Puzzle

adzm

here I was thinking about operator precedence and semicolon insertion and it was something entirely unexpected.

gitpusher

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.