1. Обратная совместимость
JavaScript - это реализация ECMAScript . Большинство из этих функций были введены в ECMAScript 5 (ES5), однако многие старые браузеры, которые все еще имеют достаточно значительную долю рынка, не поддерживают эти функции (см. Таблицу совместимости ECMAScript 5 ), наиболее заметной из которых является IE8.
Как правило, библиотеки возвращаются к собственной реализации, если она существует, в противном случае они используют собственный полифилл, например, давайте посмотрим на реализацию AngularJS ( angular.js L203-257 ):
function forEach(obj, iterator, context) {
var key;
if (obj) {
if (isFunction(obj)){
for (key in obj) {
// Need to check if hasOwnProperty exists,
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
iterator.call(context, obj[key], key);
}
}
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
} else {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
}
}
return obj;
}
Следующие строки проверяют, forEach
существует ли метод на объекте и является ли он версией AngularJS или нет. Если нет, он использует уже указанную функцию (нативная версия):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
}
2. Удобство
В нативном JavaScript Array.prototype.forEach
это метод, эксклюзивный для экземпляра Array
, но большинство Object
any тоже итерируемо.
По этой причине многие создатели библиотек делают свои функции полиморфными (способными принимать в качестве входных данных несколько типов). Давайте возьмем приведенный выше код AngularJS и посмотрим, какие входные данные он принимает:
Функции :
if (isFunction(obj)){
for (key in obj) {
// Need to check if hasOwnProperty exists,
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
iterator.call(context, obj[key], key);
}
}
Массивы (с собственной поддержкой forEach):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
Подобные массиву объекты, включая Array (без встроенной поддержки forEach), String, HTMLElement, Object с допустимым свойством длины:
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
Объекты:
} else {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
}
Заключение
Как вы можете видеть, AngularJS будет перебирать практически любой объект JavaScript, хотя он работает так же, как и нативная функция, он принимает гораздо более разные типы ввода и, таким образом, является допустимым дополнением к библиотеке, а также способом вызова функций ES5. в устаревших браузерах.