Warum haben JavaScript-Frameworks / -Bibliotheken Funktionen, die in reinem JavaScript bereits vorhanden sind?

60

Ich frage mich, warum Frameworks / Bibliotheken ihre eigenen Helfer haben, obwohl sie von Haus aus bereits existieren.

Nehmen wir jQuery und AngularJS . Sie haben ihre eigenen eachIteratorfunktionen:

Aber wir haben Array.prototype.forEach.

Ähnlich,

Aber wir haben die JSON.parse()Funktion in Vanille JavaScript.

Cihad Turhan
quelle
75
Als jemand, der sich an die schlechten alten Tage der Webentwicklung erinnert, bringt mich diese Frage zum Weinen.
Josh3736
3
@ Josh3736 Zumindest müssen Sie nicht noch IE6 unterstützen ('tho, zum Glück nur in einer "machen es funktioniert, kann es Mist aussehen" Weise)
Izkata
12
jQuery.eachund Array.prototype.forEachsind nicht gleichwertig.
zzzzBov
3
Was Sie sich fragen sollten, ist: Wie viele der Funktionen, die in vanillaJS jetzt enthalten sind, stammen von Toolkits wie jQ und dergleichen? Die Antwort lautet: viele . Dies wirft die Frage auf: Warum verwenden wir sie immer noch? Warum sollte man jQuery's einbinden $.eachund nicht das native (und schnellere) verwenden Array.prototype.forEach?
Elias Van Ootegem
1
@ Josh3736 Es ist ok bro ... i.stack.imgur.com/HJs4V.jpg
Crono

Antworten:

93

Denn als diese Bibliotheken geschrieben wurden, haben einige große Browser diese Funktionen nicht unterstützt. Einmal geschrieben und verwendet, können diese Funktionen nicht aus diesen Bibliotheken entfernt werden, ohne viele Anwendungen zu beschädigen.

(In diesem Fall bedeutet "Hauptbrowser" einen Browser, der immer noch einen großen Marktanteil hat, einschließlich älterer Versionen von Browsern wie Internet Explorer, bei denen eine große Anzahl von Benutzern nicht unbedingt auf die neueste Version aktualisiert.)

Gort den Roboter
quelle
44
$ ('Laufschrift'). each (function () {$ (this) .append ($ ('<bgsound />', {src: "good-answer.mp3"}));});
Pierre Arlaud
36
@dirkk Es ist nicht so, dass neuere Browser dies nicht unterstützen. Es ist so, dass nicht jeder das Glück hat, ein Publikum zu haben, das einen aktuellen Browser verwendet.
George Reith
14
Array.prototype.forEachiteriert nur über Arrays - beide Bibliotheksiteratorfunktionen können über Arrays oder Objekte iterieren.
JoeG
3
Die Funktionen unterstützen alte Browser und alten Code, der die Bibliothek aufruft und den der Programmierer nicht umschreiben möchte. Auch wenn Sie die Unterstützung für IE 6 eingestellt haben, haben Sie wahrscheinlich immer noch JavaScript im Einsatz, als Sie alte Kopien von IE unterstützen mussten.
Michael Shopsin
6
Viele dieser Funktionen (zB jQuery.parseJSON ()) prüfen nur, ob der Browser dies unterstützt und stellen sich dann auf die Browsermethode ein und verwenden nur eine Alternative bei nicht kompatiblen Browsern!
Josef
35

Weil unterschiedliche Browser unterschiedliche Implementierungen und Funktionen in ihrer JavaScript-Engine haben. Derselbe "Vanilla-JS" -Code kann in zwei verschiedenen Browsern oder sogar in zwei verschiedenen Versionen desselben Browsers unterschiedlich ausgeführt werden.

Die Abstraktionsschicht, die von gängigen JS-Bibliotheken bereitgestellt wird, ist ein Weg, um dies zu umgehen. Hinter den Kulissen werden die Kapazitäten und Einschränkungen der verschiedenen Browser umgangen und darüber hinaus eine einheitliche, benutzerfreundliche API bereitgestellt. Dies ermöglicht wiederum, dass allgemeine Vorgänge wie das Abrufen eines DOM-Objekts oder das Abrufen von JSON-Daten konsistent, effizient und browserunabhängig sind.

Dies erleichtert Entwicklern das Leben erheblich, die sich jetzt darauf konzentrieren können, was Code tun soll, anstatt wie er für die Arbeit mit Browser X oder Y geschrieben werden soll.

Crono
quelle
2
Das Verhalten von "Core JS" ist in allen Browsern gut spezifiziert und getestet.
Domenic
2
Abgesehen von der @Domenic-Syntax unterscheiden sich Javascript-Implementierungen von Browser zu Browser. Es gibt Eigenschaften, Methoden, Ereignisse und Funktionen, die Sie nur in wenigen Browsern oder manchmal auch nur in einem finden.
Crono
1
Ja, Browser verfügen über nicht standardmäßige Funktionen. Das hat nichts mit den in dieser Frage diskutierten Standardfunktionen zu tun.
Domenic
8
@Domenic Wenn Sie unter "in der Frage diskutierte Standardfunktionen" die Array.prototype.forEachund JSON.parse-Funktionen verstehen , zeigt Ihnen eine schnelle Suche bei Google, dass Sie sich geirrt haben. JSONObjekt wurde in IE7 nicht unterstützt und forEachwar in einigen Opera-Versionen nicht definiert. Bibliotheken wie jQuery kannten diese Einschränkungen jedoch nicht und arbeiteten hinter den Kulissen daran. Also ich denke meine Antwort steht.
Crono
27

1. Abwärtskompatibilität

JavaScript ist eine Implementierung von ECMAScript . Die meisten dieser Funktionen wurden in ECMAScript 5 (ES5) eingeführt, jedoch unterstützen viele ältere Browser, die immer noch einen ausreichenden Marktanteil haben, diese Funktionen nicht (siehe ECMAScript 5-Kompatibilitätstabelle ). Die bekanntesten sind IE8.

Im Allgemeinen werden Bibliotheken auf die native Implementierung zurückgreifen, wenn sie ansonsten vorhanden sind. Verwenden Sie eine eigene Polyfüllung. Schauen wir uns beispielsweise die AngularJS-Implementierung an ( 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;
}

In den folgenden Zeilen wird überprüft, ob die forEachMethode für das Objekt vorhanden ist und ob es sich um die AngularJS-Version handelt. Wenn nicht, wird die bereits angegebene Funktion (die native Version) verwendet:

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

2. Bequemlichkeit

In nativem JavaScript Array.prototype.forEachist eine Methode exklusiv für eine Instanz von Array, die meisten Objectsind jedoch auch iterabel.

Aus diesem Grund machen viele Bibliotheksersteller ihre Funktionen polymorph (sie können mehrere Typen als Eingabe akzeptieren). Nehmen wir den obigen AngularJS-Code und sehen, welche Eingaben akzeptiert werden:

Funktionen :

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);
    }
  }

Arrays (mit nativem forEach-Support):

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

Array-ähnliche Objekte, einschließlich Array (ohne native forEach-Unterstützung), String, HTMLElement, Object mit einer gültigen length-Eigenschaft:

} else if (isArrayLike(obj)) {
  for (key = 0; key < obj.length; key++)
    iterator.call(context, obj[key], key);

Objekte:

} else {
  for (key in obj) {
    if (obj.hasOwnProperty(key)) {
      iterator.call(context, obj[key], key);
    }
  }
}

Fazit

Wie Sie sehen, durchläuft AngularJS die meisten JavaScript-Objekte, obwohl es genauso funktioniert wie die native Funktion. Es akzeptiert weitaus mehr verschiedene Eingabetypen und ist somit eine gültige Ergänzung der Bibliothek sowie eine Möglichkeit, ES5-Funktionen zu implementieren zu älteren Browsern.

George Reith
quelle
2
Möglicherweise möchten Sie Ihren Link aktualisieren, um auf ein bestimmtes Commit (z. B. angle.js L203-257 ) zu verweisen, damit Sie später darauf zugreifen können, sobald sich masterÄnderungen ergeben.
Whymarrh