On the zoomed-in scale we see things like tricky semantics for regexp or Math.round(), which major implementations still get wrong.
On the zoomed-out scale, we see things like property iteration order. This touches on array semantics and hidden classes. Why does v8 permit two objects to have the same properties but different hidden classes? Because JS requires that properties be enumerated in their definitional order - something no other language requires, and which puts serious constraints on implementations.
TypeScript can layer types on top, but can't make arrays sane or fix the other deep language issues.
But initial implementations just stored properties in a flat list, so in practice all had iteration order matching definition order. And then websites were created depending on that behavior.
So now you had a spec saying "the order can be anything" but real-world compat constraints meant that in any implementation shipping in a web browser the order had to be definition order. At some point this compat constraint was simply documented in the spec, so there wouldn't be a gotcha lurking for a new implementation.
So it's hard to blame this problem on JS, really. It's more like Postel's Law (or a failure thereof, depending on who you're talking to, but I feel like in this case the output is the iteration order, and having it be fixed corresponds to being conservative in what you do. The pages that failed on different iteration orders correspond to _not_ being liberal in what you accept from others...
5
-0
"3"
3.0
4294967294
But these are not "numerical properties:" "-0"
-1
"3.0"
4294967295
Which means that, when setting a property on an array, you must attempt to parse the object in a very peculiar way so that you can make a decision about iteration order, and whether to adjust the length property.
I wish I could just write that I'm expecting to receive a User object in a function without having to resort to TypeScript. It would make code so much more readable.