There's a big difference to strongly typed dynamic languages that go out of their way to catch programming mistakes at runtime. With JS you get some "wtf" result when things go wrong and it propagates a long way before manifesting (if it's caught at all). Combine with JS's many weird semantics and special cases that are hard to keep in mind at once...
Recent favourite (minimized case after discovering unexpected piles of NaN's in some faraway place)
> parseInt("0")
0
> parseInt("1")
1
> parseInt("2")
2
> ["0", "1", "2"].map(parseInt)
[ 0, NaN, NaN ]