Часто объекты в JavaScript используются в качестве заменителей ассоциативных массивов в других языках, таких, как PHP. Например, мы можем передать с сервера в браузер список автомобильных марок в виде пар ключ-значение, где ключами являются id марок в нашей базе, а значениями — названия марок. Скажем, «ассоциативный массив» (он же объект) будет выглядеть так:
1 |
var list = {3: "Audi", 2: "BMW", 1: "Chevrolet"}; |
Теперь выведем содержимое списка с помощью перебора по методу for-in:
1 2 3 |
for (var i in list) { alert(list[i]); } |
И тут проявляются различи между браузерами. Firefox и IE выведут в алфавитном порядке, как мы и задали. А вот Chrome и Opera отсортируют поля объекта в порядке возрастания ключа и выведут в данном случае в обратном порядке. Как же быть?
Первый вариант решения проблемы состоит в том, чтоб сделать текстовые ключи, например, задать «массив» таким образом:
1 |
var list = {"i3": "Audi", "i2": "BMW", "i1": "Chevrolet"}; |
Тогда ни один браузер не будет сортировать его по ключам, а выведет как есть. Минус этого метода состоит в том, что надо изменять формат отдаваемых сервером данных, что теоретически может привести к проблемам, если в большом проекте где-то еще есть функционал, «знающий» лишь старый формат.
Второй вариант — перед выводом превратить этот объект в настоящий javascript-массив и уже его отсортировать, не полагаясь на сортировку исходных данных и не заботясь о различиях в поведении браузеров. Сначала из объекта-«массива» создадим массив объектов, каждый из которых будет содержать поля id и name:
1 2 3 4 |
var listNew = []; for (var i in list) { listNew.push({ id: i, name: list[i]}); } |
Теперь можно массив listNew отсортировать, воспользовавшись методом .sort(). Но дело в том, что сортируем-то мы не строки, а объекты, поэтому нельзя просто взять и запустить сортировку, сначала нужно написать функцию сравнения элементов массива между собой:
1 2 3 4 5 |
function compareObjects (a, b) { if (a.name > b.name) return 1; if (a.name < b.name) return -1; return 0; }; |
После этого можно легко отсортировать наш новый массив, применив данную функцию для сравнения:
1 |
listNew.sort(compareObjects); |
И наконец, можем вывести получившийся список:
1 2 3 |
for (var i = 0; i < listNew.length; i++) { alert(listNew[i].name); } |
Теперь мы увидим, что элементы массива выводятся в нужном нам алфавитном порядке и не зависят от своих id. Причем, во всех браузерах одинаково.
Сотрите также цикл уроков по функциям в javascript, разъясняющий их особенности в этом языке.