1. Compatibilità con le versioni precedenti
JavaScript è un'implementazione di ECMAScript . Molte di queste funzioni sono state introdotte in ECMAScript 5 (ES5), tuttavia molti browser più vecchi che hanno ancora una quota abbastanza significativa del mercato non supportano queste funzioni (si veda tabella di compatibilità ECMAScript 5 ), il più notevole di questi è IE8.
Generalmente le librerie tornano all'implementazione nativa se esiste altrimenti usano il proprio polyfill, per esempio esaminiamo l'implementazione di 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;
}
Le seguenti linee controllano se il metodo forEach
esiste sull'oggetto e se è la versione di AngularJS o meno. Altrimenti usa la funzione già specificata (la versione nativa):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
}
2. Convenienza
In JavaScript nativo Array.prototype.forEach
è un metodo esclusivo per un'istanza di Array
, tuttavia la maggior parte di qualsiasi Object
è iterabile.
Per questo motivo molti creatori di librerie fanno le loro funzioni polymorphic (in grado di accettare più tipi come input) . Prendiamo il codice AngularJS sopra e vediamo quali input accetta:
Funzioni :
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);
}
}
Array (con supporto nativo forEach):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
Oggetti tipo array inclusa Array (senza supporto nativo forEach), String, HTMLElement, Object con una proprietà length valida:
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
oggetti:
} else {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
}
Conclusione
Come puoi vedere, AngularJS esegue iterazioni sulla maggior parte degli oggetti JavaScript, sebbene funzioni allo stesso modo della funzione nativa accetta tipi di input molto più diversi e costituisce quindi un'aggiunta valida alla libreria e un modo di portando le funzioni ES5 ai browser legacy.