Tady se přidám ke Kitovi - fakt si ten manuál přečti.
V JS operátor == nemá význam
"porovnej 'a' a 'b' podle obsahu", ale
"porovnej 'a' a 'b' a v případě potřeby je přetypuj". V tom je jádro problému.
'aa' == new String('aa')
Tady porovnáváš hodnotu s objektem. No a objekt není hodnota. Je to sice nešťastné, ale je to tak právě proto, že to je konzistentní se zbytkem. Samozřejmě by to mohlo být lepší, ale na webu má zpětná kompatibilita takovou prioritu, takže třeba změny chování operátoru pro porovnání nepřipadají moc v úvahu. Pokud se s tím někdo smířit nedokáže, tak má na výběr ze stovek transpilovaných jazyků. Každopádně vytvářet řetězce pomocí new String jsem snad ani nikde neviděl, nikdo to nepoužívá.
new String('aa') == new String('aa')
{} == {}
Tady zase porovnáváš objekt s objektem. No a shodné objekty to nejsou. Tzn. je to konzistentní.