2011-12-28 3 views
3

У меня есть ситуация, когда я пытаюсь сделать работу с array, но я просто не думаю, что это будет. Я хочу иметь список объектов, каждый из которых имеет уникальный идентификатор, и я хочу иметь возможность легко ссылаться на конкретный объект, не зацикливая массив, ищущий этот идентификатор.Являются ли «for ... in» циклы в Javascript всегда плохими?

Если я использую object, я могу легко использовать уникальный идентификатор в качестве ключа и объекта в качестве значения. Однако, если я использую объект вместо массива, мне придется использовать цикл for...in, и я знаю, что есть проблема, связанная с этим, если кто-то, использующий мой код, расширил Object.prototype.

Так вот мой вопрос:

Является ли это на самом деле, что часто люди простираться Object.prototype, что я должен быть устал от его использования? Существуют ли другие причины, по которым я не хочу использовать цикл for...in?

С другой стороны, является ли производительность хитом цикла в массиве, который ищет уникальный идентификатор, настолько минимальный, что я не должен беспокоиться о нем?

(Для записи у массива, вероятно, будет довольно мало элементов, но я получаю доступ к нему очень часто. Кроме того, код, который я пишу, будет плагином jQuery, поэтому я не могу контролировать его что другие плохие кода люди совмещая ее с)

UPDATE:.

на основе рекомендаций от @nnnnnn, я создал тест JSPerf и вот результаты: http://jsperf.com/accessing-object-properties-vs-iterating-over-arrays

в основном, хотя объект путь немного быстрее, differen ce незначительно. Тем не менее, использование for...in с hasOwnProperty кажется чище.

+1

Нет, они только как правило, «плохо», когда один использует конструкцию злоумышленником * массив *, с ожиданием для-каждого, который находится в другом языки. (Ответы охватывают остальные.) –

ответ

2

Так вот мой вопрос:

Является ли это на самом деле, что часто люди простираться Object.prototype, что я должен быть устал от его использования? Существуют ли другие причины, по которым я не хочу использовать цикл for ... in?

Нет, это не распространено, но это происходит. Вы должны использовать цикл for..in в любом случае, но с .hasOwnProperty(), как показано в других ответах.

Я не могу придумать никаких причин для не использовать a для ..in (на объекте, очевидно, вы не используете его на массиве).

С другой стороны, является ли производительность хитом цикла в массив, ищущий уникальный идентификатор, настолько минимальным, что я не должен беспокоиться о нем?

Ну, вы упомянули, что у вашего массива не будет много элементов, но все же я думаю, что даже если бы он выполнялся хорошо, он бы без лишних трудностей усложнил ваш код, учитывая, что вам вообще не нужно делать это для объектов. С другой стороны, использование .hasOwnProperty() является незначительным осложнением, которое эффективно становится частью синтаксиса для каждого из них.

Вы можете настроить тест производительности здесь: http://jsperf.com/

5

Даже если кто-то продлит прототип, вы можете использовать свойство hasOwnProperty, чтобы исключить этих участников. This is exactly what Sugar.js recommends:

var s = 'cat', key; 
for(key in s) { 
    if(s.hasOwnProperty(key)) { 
    console.log(key); 
    } 
} 

Теперь в соответствии с сахаром, for..in является общепринятой петлей для литералов объектов, но вы также можете использовать итератор как $.each для JQuery или _.each для Underscore.js.

+0

'hasOwnProperty' работает только с объектами, которые наследуются от' Object'. Я знаю, что смогу это сделать, но я действительно надеялся найти решение, которое не связано с созданием нового «класса». Я также надеялся на ответ на мой вопрос об итерации массивов и объектов с точки зрения производительности. –

+2

@Philip Walton - Подождите, что? У вас есть объекты, которые не наследуются от 'Object'? Почему, по-вашему, вам нужно создать новый «класс» для использования '.hasOwnProperty()'? – nnnnnn

+0

@nnnnnn Doh! Спасибо что подметил это. Я был (ошибочно) под впечатлением, что 'hasOwnProperty' не работал над объектными литералами, а только на других объектах, которые наследуются от корневого класса Objecet. –

2

Вы можете использовать метод hasOwnProperty в цикле for..in, чтобы отличать материал дальше цепочкой прототипов от материалов, присвоенных вашему объекту.

Или вы можете сохранить свой собственный список «ключей», назначенных данному объекту.

Смежные вопросы