I think the problem in your case is not the code. It's the browser.
You can read more about it here.
And here is a simple test you can run in the console.
var a = {1:'a', 3:'b', 2: 'c'};
console.log(a);
the result will be (at least on chrome and FF):
Object { 1="a", 2="c", 3="b"}
I was able to overcome this with the following trick.
In js/varien/form.js
in the class RegionUpdater
I added an other function to sort the region dropdown.
sortSelect : function (){
elem = this.regionSelectEl;
var tmpAry = new Array();
var currentVal = $(elem).value;
for (var i=0;i<$(elem).options.length;i++) {
if (i == 0) continue;
tmpAry[i-1] = new Array();
tmpAry[i-1][0] = $(elem).options[i].text;
tmpAry[i-1][1] = $(elem).options[i].value;
}
tmpAry.sort();
while ($(elem).options.length > 0) {
$(elem).options[0] = null;
}
for (var i=1;i<=tmpAry.length;i++) {
var op = new Option(tmpAry[i-1][0], tmpAry[i-1][1]);
$(elem).options[i] = op;
}
$(elem).value = currentVal;
return;
}
and just call this function inside the update
function of the same class.
Right before if (this.disableAction=='hide') {
add this line
this.sortSelect();