web-dev-qa-db-fra.com

Pourquoi les frameworks / bibliothèques JavaScript ont-ils des fonctions qui existent déjà en JavaScript pur?

Je me demande pourquoi les frameworks/bibliothèques ont leurs propres aides alors qu'ils existent déjà nativement.

Prenons jQuery et AngularJS . Ils ont leurs propres fonctions d'itérateur each:

Mais nous avons Array.prototype.forEach.

De même,

Mais nous avons la fonction JSON.parse() dans Vanilla JavaScript.

61
Cihad Turhan

Parce que lorsque ces bibliothèques ont été écrites, certains principaux navigateurs ne prenaient pas en charge ces fonctionnalités. Une fois écrites et utilisées, ces fonctionnalités ne peuvent pas être supprimées de ces bibliothèques sans interrompre de nombreuses applications.

(Dans ce cas, "navigateur principal" signifie un navigateur qui détient toujours une part de marché importante, qui comprend des versions plus anciennes de navigateurs comme Internet Explorer, où un grand nombre d'utilisateurs ne mettent pas nécessairement à niveau vers la dernière version.)

94
Gort the Robot

Parce que différents navigateurs ont différentes implémentations et fonctionnalités cuit dans leur moteur JavaScript. Le même code "Vanilla-JS" peut s'exécuter différemment sur deux navigateurs différents, voire deux versions différentes du même navigateur.

La couche d'abstraction fournie par les bibliothèques JS populaires est un moyen de contourner ce problème. Dans les coulisses, il fonctionne en fonction des capacités et des limites des différents navigateurs et offre une API unifiée et facile à utiliser. Cela, à son tour, permet aux opérations courantes telles que l'obtention d'un objet DOM ou la récupération de données JSON d'être cohérentes, efficaces et indépendantes du navigateur.

Cela rend la vie beaucoup plus facile pour les développeurs qui peuvent désormais se concentrer sur ce que le code doit faire, plutôt que sur la façon dont il doit être écrit pour fonctionner avec le navigateur X ou Y.

35
Crono

1. Compatibilité descendante

JavaScript est une implémentation de ECMAScript . La plupart de ces fonctions ont été introduites dans ECMAScript 5 (ES5), mais de nombreux navigateurs plus anciens qui détiennent encore une part suffisamment importante du marché ne prennent pas en charge ces fonctions (voir tableau de compatibilité ECMAScript 5 ), le plus notable de ceux-ci étant IE8.

Généralement, les bibliothèques reviendront à l'implémentation native si elle existe sinon utilisez leur propre polyfill, par exemple, regardons l'implémentation d'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 méthode forEach 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 est une méthode exclusive à une instance de Array, mais la plupart des Object sont également itérables.

Pour cette raison, de nombreux créateurs de bibliothèques rendent leurs fonctions polymorphes (capables d'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 prise en charge native de forEach):

} else if (obj.forEach && obj.forEach !== forEach) {
  obj.forEach(iterator, context);

Objets de type tableau y compris Array (sans prise en charge forEach native), 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 voir, AngularJS itérera sur la plupart des objets JavaScript, bien qu'il fonctionne de la même manière que la fonction native, il accepte des types d'entrée beaucoup plus différents et constitue donc un ajout valide à la bibliothèque ainsi qu'un moyen d'apporter des fonctions ES5. aux navigateurs hérités.

28
George Reith