2008-12-19

Корректный способ итерации сквозь объекты

программирование, JavaScript

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

Допустим, у нас есть объект созданный вот таким образом:

var obj = {property1:"свойство 1",property2:"свойство 2"};

вот самый распространенный НЕПРАВИЛЬНЫЙ способ показать все свойства объекта:

for(key in obj){
        alert(key);
}

Вроде все работает правильно и на экране действительно последовательно покажутся все свойства объекта. Почему такой способ является неправильным?

Добавим перед циклом вот такую строчку:

Object.prototype['test1'] = "test1 value";

При запуске скрипта еще раз оказывается, что наш объект волшебным образом приобретает еще одно свойство - test1, хотя мы его не создавали! Это значит что любая сторонняя библиотека которая таким способом расширяет функциональность стандартных классов JavaScript, например prototype.js способна непредсказуем образом изменить логику работы ваших программ. В данном случае хорошим тоном является сравнение текущего свойства и свойства прототипа при каждой итерации, если они равны, значит ничего не делаем:

for(key in obj){
   if (obj.constructor.prototype[key]!==obj[key]){
      alert(obj[key]);
   }
}

Обратите внимание, что здесь использовано строгое сравнение !==. Все просто, все логично, вот только набирать это каждый раз довольно утомительно, поэтому создадим вот такую функцию:

    function forEach(obj,fn){
        for(key in obj){
            if (obj.constructor.prototype[key]!==obj[key]){
                if (fn(key)===false) break;
            }
        }
    }

В этом случае итерация запишется совсем просто:

forEach(obj,function(key){
    alert(obj['key']);
});

Обратите внимание, что в функции forEach есть возможность остановить итерацию досрочно, что бывает полезно например при поиске элемента, для этого достаточно возвратить false:

forEach(obj,function(key){
    alert(obj['key']);
    if (key=='property1') return false;
});

 

 

комментарии:

 
RSS комментариев

Для того чтобы каждый раз не представляться можно войти как зарегистрированный пользователь.

Имя*

разрешены только теги br, font, span, p, strong, u, p, blockquote, a, div, img - остальные будут безжалостно удаляться

разное (190)
howto (124)
программирование (109)
гад-же-ты (75)
мысли (42)
PHP (41)
JavaScript (39)
вебмастеринг (37)
linux (29)
гондураша (28)
юмор (25)
полезное (21)
движок (17)
Android (17)
софт (15)
кино (14)
деньги (14)
видео (13)
diy (11)
путешествия (10)
беспредел (10)
книги (10)
музыка (10)
интернет (10)
умный дом (8)
занимательная физика (8)
ztools (8)
языки (7)
Nokia 5800 (7)
хостинг (7)
lifehack (6)
вебдизайн (6)
css (6)
arduino (5)
apple (5)
связной (5)
прелоадер (5)
козлы (5)
oDesk (5)
кухня (4)
svn (4)
движек (4)
аниме (4)
Python (4)
занимательная юриспруденция (4)
software (3)
synphony (3)
рестораны (3)
энергия (3)
спорт (2)
фото на документы (2)
webmastering (2)
гитара (2)
Берлин (2)
Java (2)
bash (2)
Ruby on Rails (2)
гаджеты (2)
дурдом (1)
авторское право (1)
восстановить (1)
C++ (1)
технологии (1)
годнурас (1)
микросервисы (1)
сайты (1)
наука (1)
programming (1)
SEO (1)
Приехал ESP32 - Cam (1)
Поиск по блогу:

Valid XHTML 1.0 Strict