molily: Kein Zugriff auf Objekt

Beitrag lesen

Ich hätte das mit einem weiteren Parameter für den Callback gelöst. Ansonsten kommt man, wenn man this sinnvoll setzt, nicht an die Settings.
Warum nicht?

Wie komm ich sonst daran?
Klar, ich kann Funktionen so verschachteln, dass ich die Settings, die ich an $.ajax() übergebe, im Success- und Error-Handler zur Verfügung habe. Aber:

  • Funktionen zu verschachteln erzeugt schwer lesbaren Code
  • Verschachtelte Funktionen sind Closures mit allen Vor- und Nachteilen
  • In OOP will ich ggf. eine Objektmethode als Handler verwenden, keine anonyme verschachtelte Funktion

Die liegen (hier und im unittestfall) im Scope des Callbacks.

Im Fall von https://github.com/jquery/jquery/blob/2.1.0/test/unit/ajax.js#L151-L183 gibt es außer »this« keine Möglichkeit, auf das letztlich verwendete Settings-Objekt zuzugreifen. Das Settings-Objekt ist in keiner Variable in einem der äußeren Scopes gespeichert.

Wenn ich $.get(), $.getJSON(), $.post() usw. anstatt der Low-Level-Funktion $.ajax() verwende, dann lässt kann ich das erzeugte Settings-Objekt auch nicht per Closure den Handlern zugänglich machen, denn es wird intern erzeugt.

Bei der Objektorientierten Programmierung will man meist selbst this verwenden, um das aktuelle Objekt zu referenzieren.
Aber abraten, wenn der Defaultcontext definiert ist? Warum?

Sagte ich ja: Weil man den Kontext selbst kontrollieren will. Stichwort Function Binding.

Klar, event.currentTarget ist viel intuitiver, in der Doku ist es auch nur angedeutet(als Beispiel), oder ich habe es wieder übersehen, aber warum pfui?

Der Kontext von Event-Handlern ist seit langem so in »DOM 0« (sprich seit Netscape 2.0) definiert. Klar, das ist äußerst robust – jQuery hat es nicht erfunden, sondern macht dasselbe, was bei element.onevent = function() { alert(this) } bzw. element.addEventListener('event', function() { alert(this) }) passiert. Es ist allerdings nicht sprechend und bricht, sobald irgendwie anders der Kontext gesetzt wird. Den Kontext von Event-Handlern auf das View-Objekt zu setzen ist das erste, was man bei objektorientierter GUI-Programmierung tut. Das machen alle Frontend-JavaScript-Frameworks, die ich kenne.

Was heißt kaputt? Soweit ich das jetzt sehe, haben die sich tatsächlich bei jedem Callback gedanken über den Context gemacht.

Ja, aber warum überhaupt? Dass eine Bibliothek wie jQuery, welche einen sehr begrenzten Bereich der JavaScript-Programmierung abdeckt, den Funktionskontext mit Bedeutung versieht, ist ein großes Problem. Man sollte es den Entwicklern überlassen, du auf Basis von jQuery High-Level-Anwendungen entwickeln.

Es gibt verschiedene Möglichkeiten, Low-Level-jQuery mit eigenem Code zu verdrahten:

  • Funktional
      - Daten durch die Scope-Chain bereitstellen (Funktionsverschachtelung, Closures)
      - Parameter übergeben bzw. vorbelegen (Partial Application)
  • Objektorientiert
      - Den Kontext auf ein eigenes Objekt setzen (Function Binding)

Closures sind wohl die häufigste Technik, aber sie skaliert nicht gut. Partial Application ist wenigen bekannt. Im OOP-Bereich bleibt nur Function Binding.

Wenn du meinst, der Context ist von außen ohne Doku sowieso nicht ersichtlich und man hätte diesen von daher besser aufs global object gesetzt, dann bin ich bei dir.

Ja. Der Kontext sollte gar nicht forciert werden. Dann ist er derjenige, der vom Entwickler gesetzt wurde, bzw. als Fallback window oder undefined (im ES5 Strict Mode).

Mathias