apparently codepen runs the code through a parser and inserts exit checks in all detectsble loops.
https://blog.codepen.io/2016/06/08/can-adjust-infinite-loop-...
as for why no races I think because it's basically impossible (or way too non performant) to write a JavaScript engine that can handle multiple threads deleting properties on objects. You'd have to lock on every delete.
That's the nature of JIT though, non-performant but working is ok for the bits that might cause trouble. JavaScript should just make fast the things it can.
I'd be ok for a light pre-emtion that would happen between javascript statements. Instead of genuain preemtion have the Javascript engine include break checks. A check of a flag and conditional branch (usually not taken) is not a huge expence. The cost can be especially ameliorated if you do the check only on statements that jump to earlier statements.
That fixes the problem of long running code stopping other things. It doen't need system level threads or parallelism, just a js engine doing spot checks.
for example
Typing this into a livecoding environment breaks because the while loop goes on forever until you type the code to increment x. It breaks everything because the while loop blocks you from being able to type the code that would get you out of the situation.I don't see the wisdom of disaallowing something due to the specter of race conditions when its absence seems to cause a much easier to cause debilitating problem.