1. Compatibilité descendante
JavaScript est une implémentation de ECMAScript . La plupart de ces fonctions ont été introduites dans ECMAScript 5 (ES5). Cependant, de nombreux navigateurs plus anciens, qui possèdent encore une part assez importante du marché, ne prennent pas en charge ces fonctions (voir tableau de compatibilité ECMAScript 5 ), le plus notable étant IE8.
Généralement, les bibliothèques reviendront à l'implémentation native si elle existe, sinon elles utiliseront leur propre polyfill, par exemple, implémentons 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;
}
Les lignes suivantes vérifient si la forEach
méthode existe sur l’objet et s’il s’agit de la version AngularJS ou non. Sinon, il utilise la fonction déjà spécifiée (la version native):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
}
2. Commodité
En JavaScript natif, Array.prototype.forEach
cette méthode est exclusive à une instance de Array
. Toutefois, la plupart des Object
modifications sont également itérables.
Pour cette raison, de nombreux créateurs de bibliothèques rendent leurs fonctions polymorphes (pouvant accepter plusieurs types en entrée). Prenons le code AngularJS ci-dessus et voyons quelles entrées il accepte:
Fonctions :
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);
}
}
Tableaux (avec support natif pour chaque):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
Objets de type tableau, y compris Array (sans support natif de forEach), String, HTMLElement, Object avec une propriété de longueur valide:
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
Objets:
} else {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
}
Conclusion
Comme vous pouvez le constater, AngularJS itérera sur la plupart des objets JavaScript, bien que fonctionnant de la même manière que la fonction native, il accepte beaucoup plus de types d’entrées et constitue donc un ajout valable à la bibliothèque ainsi qu’un moyen d’apporter des fonctions ES5. aux anciens navigateurs.