il punto e' che "i" e' un attributo del tutto arbitrario
setAttribute('id','quellochevuoi') va a "scrivere" (o a sostituire quanto presente come id) nell' xhtml dell' elemento, come se cambiasse nel markup vero e proprio, e' un attributo valido e richiesto restituisce la stessa cosa come this.id sia come this.getAttribute('id')[*]
"i" no, lo scrivi a livello di markup dove l' xhtml non permette di avere attributi arbitrari
e il browser e' libero di restare aderente allo standard oppure comportarsi lascivamente (...tradizionalmente IE...)
se tu settassi [**] element.i=i
non dovrebbe dare errore alert(this.i)
ma chiaramente non vi troveresti quanto atteso in this.getAttribute('i')
potrei sbagliare ma questo e' quanto credo succeda
[*]
per es. il value di input text e' diverso, quello che e' scritto nel markup, che rilevi col getAttribute, e' diverso da quanto rilevi col .value
[**] e se non vado errato questo genera memory leakage in IE e va ripulito