Маэстро,
при использовании for (... in ...) порядок перебора свойств в спецификации неопределён, поэтому разные браузеры перебирают их в разном порядке. Если нужно перебрать свойства в определённом порядке, следует использовать другие способы. |
У меня тоже мысли крутились вокруг "prototype", но до хэша имен ключей я так и не добрался.
Что касается Вашего примера, то (как я понял) в этом алгоритме надо каким-то образом всегда знать длину length (то ли подсчитывать её при присвоении свойств, то ли запускать общий подсчет позже). Я считаю, что если вводить сортировку (чтобы привести в разных браузерах к единому виду), то это может потратить приличное время на больших массивах. Поэтому я вообще отказался от неё и в каком порядке идет перебор в "for (var key in m)" меня уже и не интересует. Вот мой вариант решения: m = {}; m[7]='7777'; m[6]='6666'; m[5]='5555'; m[1]='1111'; m[17]='1717'; m[2]='2222'; m[25]='2525'; m[3]='3333'; m[8]='8888'; var r = 4; // удаляем свойство №4 и сдвигаем все свойства с номерами более 4 на его место var tmp = {}; for (var key in m) { if (key > r) tmp[key-1] = m[key]; else tmp[key] = m[key]; }; alert('4=' + m[4] + ' 5=' + m[5] + ' 6=' + m[6] + ' 7=' + m[7]); // 4=undefined 5=5555 6=6666 7=7777 m = tmp; alert('4=' + m[4] + ' 5=' + m[5] + ' 6=' + m[6] + ' 7=' + m[7]); // 4=5555 5=6666 6=7777 7=8888 |
Цитата:
Короче, я вообще обошел проблему с сортировкой (см. пример выше) |
Цитата:
Цитата:
|
Цитата:
for (i in obj) length++; obj.length = length; после этого добавлять \ уменьшать это значение при добавлении \ удалении элементов - т.е. придётся делать это через серреты и геттеры. |
Цитата:
Цитата:
//for (i in obj) length++; obj.length = length; // melky Array.prototype.associate = function(keys){ var obj = {}, length = Math.min(this.length, keys.length); for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; return obj; }; var hash = ['one', 'three', 'two'].associate(['first','3','2']); var string = ''; for (var i in hash) string += i + ':' + hash[i] + '; '; alert(string); // Chrome: 2:two; 3:three; first:one; // Opera: 2:two; 3:three; first:one; // FF: first:one; 3:three; 2:two; // IE: first:one; 3:three; 2:two; |
Цитата:
Может надо делать obj.length = length - 1; ? |
Цитата:
http://es5.javascript.ru/x15.4.html#x15.4.4.12 вообще, самым быстрым вариантом будет вариант Slavenin, при приведении примитивов в объекты, конечно. Цитата:
Цитата:
Цитата:
было бы неплохо не учитывать унаследованные свойства и проверять ключ на принадлежность к числу. var length = 0, i; for (i in obj) if (obj.hasOwnProperty(i) && isFinite(i)) { length += 1; } obj.length = length; |
Цитата:
Цитата:
Не знаю, что Вы подразумевали под "длиной значений", но для нормальной работы Вашего алгоритма в length должно быть не количество элементов (свойств объекта), а максимальный индекс свойства (это максимальное значение ключа), увеличенный на 1. Причем IE как всегда выпендрился: ему не надо к length прибавлять 1, иначе в объекте остается одно лишнее свойство (последнее). Код получился такой: var myObj = {}; myObj.length = 0; // это не количество элементов, а максимальный индекс + 1 myObj[1]= "1"; myObj[3]= "3"; myObj[2]= "2"; myObj[0]= "0"; myObj[100]= "100"; myObj[99]= "99"; var length = 0; // подсчет length как количества свойств ///for (i in myObj) length++; // подсчет length как максимального индекса for (i in myObj) { if (i > length) length = Number(i); }; if (window.IE) myObj.length = length; else myObj.length = length + 1; var s = ''; for (var key in myObj) s = s + ' ' + key + '=' + myObj[key]; alert('1). ' + s); // 1). 0=0 1=1 2=2 3=3 99=99 100=100 length=101 Array.prototype.splice.call(myObj, 2, 1); // удаляем один элемент var s = ''; for (var key in myObj) s = s + ' ' + key + '=' + myObj[key]; alert('2). ' + s); // 2). 0=0 1=1 2=3 98=99 99=100 length=100 |
Часовой пояс GMT +3, время: 03:57. |