Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Работа с прототипами (https://javascript.ru/forum/misc/51109-rabota-s-prototipami.html)

demoniqus 24.10.2014 11:56

Работа с прототипами
 
Добрый день!
Столкнулся с интере... совсем не прикольной особенностью работы с прототипами. На сайте, над которым работаю, используется сторонняя js-библиотека, которая в прототип массивов лепит свои дополнительные методы. При работе в большинстве браузеров эти методы не мешают - используемый цикл for in нормально проходит по элементам массива, но не трогает добавленные методы. При том, если в отладчике написать []["method_name"], то метод прекрасно виден, хотя при просмотре самого массива через отладчик видны лишь его элементы и ссылка на прототип. А вот IE (версия 8), как всегда, "а мы пойдем другим путем" - при просмотре через отладчик массива видно новый пункт(или элемент... хз, но пишется он в квадратных скобках) [Методы]. Ну и само собой разумеется, for in итерирует и все добавленные методы, что приводит к ошибкам...
Я с прототипами пока особо не сталкивался... так вот вопрос - это surprise from IE или тот, кто писал библиотеку, что-то не учел? Или IE ведет себя именно так, как это где-нибудь описано? Ежели последнее, тогда какого лешего на msdn (http://msdn.microsoft.com/ru-ru/libr...(v=vs.94).aspx) написано, что for in итерирует по ЭЛЕМЕНТАМ?

Aetae 24.10.2014 15:32

Скорее всего библиотека для нормальных браузеров использует Object.defineProperty с параметром enumerable: false. IE8 не поддерживает этот метод, и потому библиотека для него просто пишет в прототип(это осуждается, но что поделаешь).

В принципе когда приходится работать в условиях чужих скриптов, что могут нагадить в прототип, обычно используют дополнительную проверку:
for(var key in object) if( object.hasOwnProperty(key) ) {
    //...
}
Однако, если ты имеешь дело именно с массивами, а не объектами - for in вообще употреблять для перебора не следует, как семантически так и в плане производительности. Используй обычные циклы, или(в современных браузерах/с помощью полифилов) методы массива:
var i = arr.length;
while(i--){
    //...
}
for(var i = 0, len = arr.length; i < len; i++){
    //...
}
arr.forEach(function(val){
    //...
})


Часовой пояс GMT +3, время: 11:28.