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
є ітерабельним.
З цієї причини багато творців бібліотеки роблять свої функції поліморфними (здатні приймати декілька типів як вхідні дані). Візьмемо код 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);
}
}
Масиви (з рідною підтримкою для кожного):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
Об'єкти, що нагадують масив, включаючи масив (без носія підтримки forEach), String, HTMLElement, об'єкт з дійсним властивістю довжини:
} 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 до застарілих браузерів.