não li os comentários mas já vou dar meu pitaco, principalmente sobre isso aqui:

índice != comprimento

Acho que o grande ponto se resume em entender que são duas coisas diferentes. Enquanto o índice representa as unidades lógicas do troço que você ta iterando, o comprimento representa as unidades reais do troço.

Você ta iterando sobre os índices mas navegando entre o comprimento, como são duas coisas diferentes, é normal que deva haver o decremento do comprimento para fazer a iteração pelos índices da string.

Alternativamente, o que deveria haver ao contrário dos índices começarem por 1, é haver uma função que retorna a quantidade de índices da string assim como existe para o comprimento dela, que aí você iria iterar sobre os índices navegando entre os índices da string.

Algo como isso:

let alfabeto = "abcdefghijklmnopqrstuvwxyz";

for (let i = 0; i <= alfabeto.indexLength; i++) {
  console.log(alfabeto[i]);
}

Isso manteria cada um com sua função e facilitaria quem ainda não pegou a ideia de que são coisas diferentes.

Imagina o tanto de código que foi escrito com o pressuposto de que o array começa com o índice 0, agora imagina fazer essa mudança em uma das principais linguagens e enfrentar a ira a milhares de desenvolvedores que se adaptaram com o índice 0 e a quebradeira geral dos programas.

Muito do que vemos nas linguagens existe simplesemnte devido à esse problema de mudar quando muito já foi construído em cima desse pressuposto. Javascript e seus comportamentos bizarros (como quando se usa == ao invés de ===) e seus consequentes "remendos" são mais problemáticos que o índice 0 e nem isso criou uma mudança. Se fossem resolver os problemas do Javascript, a Internet simplesmente quebraria, pois milhares de sites, plugins e bibliotecas ainda funcionam com código legado de muito anos atrás.