Если я перебираю свойства объекта, используя JQuery $.each(), есть ли индекс?

a = {b:'bb',c:'cc',d:'dd'};
$.each(a, function(index){
 // here 'index' is a string variable containing the property name, ie 'b', 'c' or 'd'.
}

Мне нужен целочисленный индекс свойства - возможно ли это без использования независимой переменной count?

2 ответа

Решение

Вы могли бы сделать это:

Object.keys( a ).forEach(function ( name, index ) {
    var value = a[name];

    name // the property name
    value // the value of that property
    index // the counter
});

Это ES5 API, поэтому вам понадобится es5-shim для IE8.

Нет, это объект. Когда вы добавляете новое свойство в объект JS, в каком положении должно находиться это свойство? Что если вы удалите свойство в середине, а затем добавите его снова? Что если вы объедините другой объект поверх оригинала, если объединяемый объект имеет свойства с одинаковыми именами в совершенно другом порядке в своем исходном коде?

Вы можете подсчитать счет, и это может сработать во многих случаях, но нет никакой гарантии, что вы получите все в том порядке, в котором вы ожидаете. Когда порядок имеет значение, вы используете массив. Когда этого не происходит, и вы хотите получить удобный доступ к вещам по имени, вы используете литерал объекта. Или вы оборачиваете массив в объект, который поддерживает карту, чтобы получить независимый массив, когда они сортируются, путем написания методов сортировки массива, которые также сортируют массив карты ключ / имя.

Кроме того, учитесь для / в циклах. Нет причин использовать jQuery для итерации объекта, не являющегося jQuery. В лучшем случае это будет немного медленнее.

Редактировать:

Что ж, если вы хотите, чтобы счетчик был запрограммирован, а не индекс, на который вы можете положиться в будущем, то я бы просто испек свой собственный тип объекта, если бы мне пришлось иметь дело с IE8, поскольку мы обычно стараемся не трогать прототип конструктора Object (хотя для нормализация к будущим спецификациям Я думаю, что это может быть хорошо, если вы можете сделать это, не нарушая такие вещи, как циклы for/in, используемые в массивах, которые обычно не будут повторять методы прототипа).

function IterableCounterObj(objLiteral){ //or perhaps something less painfully named
    this.each = function(iteratorFunc){
        var cnt = 0;
        for(var x in objLiteral){
            cnt++;
            iteratorFunc(x,objLiteral[x],cnt);
        }
    }
}

var a = new IterableCounterObj({b:'bb',c:'cc',d:'dd'});
a.each(function(name,value,count){ console.log(count); });

//too much? Here's the jQuery approach to cruft

var $i = function(objLiteral){
    return new IterableCounterObj(objLiteral);
}

$i({b:'bb',c:'cc',d:'dd'}).each(function(name,value,count){ console.log(count); });
Другие вопросы по тегам