ci sono mille ragioni per sconsigliare l'uso di chiavi associative in array ... se ti servono chiavi associative hai l'object.

L'array nasce per le chiavi numeriche, ergo grazie a Dio se imposti una proprietà la length resta invariata, ergo l'Array JS si comporta come previsto sempre!

La notazione
a["pippo"]
o
a.pippo
è esattamente la stessa cosa.

Come lo è questa
a["0"]
o
a[0]
proprio perchè a prescindere da come assegni la chiave il motore verifica sia un integer like, e lo casta, se necessario.

Nel caso dei numeri non puoi usare a.0, perchè il parser darebbe errore, lo stesso errore che darebbe usando a."pippo", ergo rimaniamo sempre nella voluta logica.

Ogni linguaggio ha un suo Array, ed il comportamento è sempre lo stesso.
new Array in JS è instanceof Object prima, ed Array poi ... ergo quello che puoi fare con l'object puoi farlo anche con l'Array, ma essendo quest'ultimo un extend di Object, gestisce indici numerici tramite overload.

Immagina che internamente c'è un get / set chiave / valore ... se chiave è int o parseInt(chiave) == chiave allora sfrutti length, altrimenti sfrutti la super classe dinamica Object.

Questo lo implementi anche con altri linguaggi, io ho un Array identico in PHP e C#, ho creato queste classi estendendo l'Object (in PHP e C#) ed ottengo lo stesso identico risultato.

Nel push, forEach, indexOf, slice, quello che vuoi ... lavori con i numeri ... altrimenti lavora come Object ... ma per performances e overhead (Array è più pesante di Object), è sempre sconsigliabile sfruttare l'Array come se fosse un Object (anche per ambiguità aggiunta durante l'utilizzo dell'istanza)