Bobby: Kein Zugriff auf Objekt

Moin

ich habe ein komisches Problem.

  
var coordinates={};  
for (var i=0; i < window.mapData.length; i ++)  
{  
    var point=window.mapData[i];  
    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?i='+i+'&address='+point.address+'&sensor=false')  
    .done(function(data)  
    {  
        var Ausdruck=/\?i\=([0-9]*?)\&/;  
        Ausdruck.exec($(this)[0].url);  
        coordinates[RegExp.$1]=data.results[0].geometry.location;  
     });  
     console.info(i);  
     console.info(coordinates);  
     console.info(coordinates[0]);  
}  
console.info(coordinates);  

das i wird korrekt ausgegeben. Das coordinates-Object wird an beiden Stellen ordentlich ausgegeben. Ich erhalte aber keinen Zugriff auf coordinates[0]

Was könnte der Grund sein?

Ergebnis:
0
Object {}
undefined
Object {}

Objekte sind wie folgt aufgebaut:

0
Object { lat=51.0939492, lng=13.7021921}
            lat
                 51.0939492

lng
                 13.7021921

1
Object { lat=51.0806841, lng=13.7099601}

lat
                 51.0806841
            lng
                 13.7099601

Ich bin echt ratlos.

Gruß Bobby

--
-> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
### Henry L. Mencken ###
-> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
## Viktor Frankl ###
ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
  1. Hi,

    Das coordinates-Object wird an beiden Stellen ordentlich ausgegeben. Ich erhalte aber keinen Zugriff auf coordinates[0]

    Was könnte der Grund sein?

    Dass dieses *Objekt* keine Eigenschaft namens "0" hat …?

    MfG ChrisB

    --
    Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
    1. Moin

      Dass dieses *Objekt* keine Eigenschaft namens "0" hat …?

      ich präzisiere: zu diesem ZEITPUNKT hat das Objekt noch keine Eigenschaft "0". Später dann ja. Es wird nicht auf die Ausführung von $.getJSON gewartet. Nun führe ich alles weitere erst aus wenn ein Ergebnis zurückgeliefert wurde. Und siehe da. Es funktioniert.

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
      ### Henry L. Mencken ###
      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
      ## Viktor Frankl ###
      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
  2. Hallo Bobby,

    var coordinates={};

    console.info(coordinates[0]);

      
    auch wenn dein Problem gelöst ist, du solltest dich schon entscheiden, ob du ein Array oder ein Objekt hast.  
      
    Gruß, Jürgen  
    
    
    1. Moin

      auch wenn dein Problem gelöst ist, du solltest dich schon entscheiden, ob du ein Array oder ein Objekt hast.

      ähm:

      Des Weiteren kann man einen numerischen Literal oder String-Literal für den Namen der Eigenschaft benutzen oder Objekte ineinander verschachteln:

      var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };  
        
      console.log(car.manyCars.b); // Jeep  
      console.log(car[7]); // Mazda  
      
      

      Merke:

      var foo = {a: "alpha", 2: "zwei"};  
      console.log(foo.a);    // alpha  
      console.log(foo[2]);   // zwei  
      //console.log(foo.2);  // Error: fehlende ) nach der Argumentliste  
      //console.log(foo[a]); // Error: a ist nicht definiert  
      console.log(foo["a"]); // alpha  
      console.log(foo["2"]); // zwei
      

      Quelle: https://developer.mozilla.org/de/docs/JavaScript/Guide/Werte_Variablen_und_Literale#Array-Literale

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
      ### Henry L. Mencken ###
      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
      ## Viktor Frankl ###
      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Hallo Bobby,

        danke für die Nachhilfe, aber du hast mir immer noch nicht erklärt, was das

          
        var coordinates={};  
                        ^  
         ...  
        console.info(coordinates[0]);  
                                ^  
        
        

        hier soll.

        Gruß, Jürgen

        1. danke für die Nachhilfe, aber du hast mir immer noch nicht erklärt, was das

          [code lang=javascript]
          var coordinates={};
                          ^
          ...
          console.info(coordinates[0]);

          Naja, bei
          coordinates=[];
          coordinates[7]=...;
          coordinates[9999]=...;
          coordinates[99999999]=...;
          macht es durchaus Sinn, das als Objekt und nicht als Array zu deklarieren.
          Da es bei Ihm die Properties aber fortlaufend sind, hat du recht, daß es eigentlich ein Array sein sollte.

          1. Moin

            Naja, bei
            coordinates=[];
            coordinates[7]=...;
            coordinates[9999]=...;
            coordinates[99999999]=...;
            macht es durchaus Sinn, das als Objekt und nicht als Array zu deklarieren.
            Da es bei Ihm die Properties aber fortlaufend sind, hat du recht, daß es eigentlich ein Array sein sollte.

            Und genau so war es auch gedacht. Wnen mal coordinaten nicht gefunden wurden, soll auch kein Eintrag erfolgen.

            Gruß Bobby

            --
            -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
            ### Henry L. Mencken ###
            -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
            ## Viktor Frankl ###
            ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
        2. Moin

          danke für die Nachhilfe,

          Sollte um Gottes Willen keine Nachhilfe sein. Das würde ich mir nie herausnehmen. Es hätte ja sein können, dass ich einem Irrtum unterliege und hab mal geteilt wo ich mein Wissen zum Teil her hab

          aber du hast mir immer noch nicht erklärt, was das

          var coordinates={};
                          ^
          ...
          console.info(coordinates[0]);
                                  ^

            
          Ja sicher hätte ich auch direkt ein Array verwenden können. da ich aber alle anderen Variablen im Object-Stil geschrieben habe, hab ich das für coordinates einfach auch gemacht... Ist doch kein Beinbruch...  
            
          Gruß Bobby  
          
          -- 
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-  
          ### Henry L. Mencken ###  
          -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-  
          ## Viktor Frankl ###  
            
          ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
          
      2. Hallo,

        Klar, Arrays in JavaScript sind nur besondere Objects. Letztlich sind die Elemente eines Arrays Objekteigenschaften, und die numerischen Indizes sind letztlich String-Eigenschaftsnamen. Arrays haben aber eine zusätzliche Magie und zusätzliche Eigenschaften und Methoden, weil sie von Array.prototype erben. Die will man auch meist benutzen. Zum Beispiel, wenn man die Liste durchlaufen will (length-Eigenschaft!).

        [code lang=javascript]var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };

        Dieses Beispiel ist zwar syntaktisch korrekt, ergibt aber keinen Sinn (warum sollte man das tun?). Natürlich kann man numerische Eigenschaftsnamen verwenden – JavaScript wandelt sie letztlich in Strings um. objekt[5] ist identisch zu objekt["5"] (Array-Magie einmal ausgenommen).

        Mathias

  3. Hi,

    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?i='+i+'&address='+point.address+'&sensor=false')
        .done(function(data)
        {
            var Ausdruck=/?i=([0-9]*?)&/;
            Ausdruck.exec($(this)[0].url);

    Was ist »this« hier? Ich nehme an, $() ist jQuery und du wrappst ein Element damit. Dann wäre url eine Elementeigenschaft. Dann könntest du auch gleich »this.url« schreiben.

    Ich kenne in HTML kein Element, das standardmäßig eine Eigenschaft url hat, aber vielleicht hsat du sie angelegt.

    coordinates[RegExp.$1]=data.results[0].geometry.location;

    Noch ein Hinweis:
    http://de.selfhtml.org/javascript/objekte/regexp.htm#exec@title=exec gibt dir die Resultate freundlicherweise als Array zurück. Das Element mit dem Index 0 liefert den gesamten Treffer, die folgenden Indizes die Teiltreffer.

    RegExp.$1 funktioniert zwar, ist aber ein Relikt aus grauer Vorzeit. Es wurde nicht standardisiert und ist schlechter Stil. Resultate eines Funktionsaufrufs an einem globalen Objekt abholen – das widerspricht sämtlichen Grundlagen der robusten Programmierung.

    Mathias

    1. Moin

      Was ist »this« hier? Ich nehme an, $() ist jQuery und du wrappst ein Element damit. Dann wäre url eine Elementeigenschaft. Dann könntest du auch gleich »this.url« schreiben.

      $(this) bezieht sich auf das getJSON Objekt. Dies hat sehr wohl eine Eigenschaft URL.

      RegExp.$1 funktioniert zwar, ist aber ein Relikt aus grauer Vorzeit. Es wurde nicht standardisiert und ist schlechter Stil. Resultate eines Funktionsaufrufs an einem globalen Objekt abholen – das widerspricht sämtlichen Grundlagen der robusten Programmierung.

      Siehst du, da bin ich wohl stehengeblieben... danke für den hilfreichen Hinweis.

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
      ### Henry L. Mencken ###
      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
      ## Viktor Frankl ###
      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Was ist »this« hier? Ich nehme an, $() ist jQuery und du wrappst ein Element damit. Dann wäre url eine Elementeigenschaft. Dann könntest du auch gleich »this.url« schreiben.

        $(this) bezieht sich auf das getJSON Objekt. Dies hat sehr wohl eine Eigenschaft URL.

        getJSON ist eine Funktion, gut auch das ist ein Objekt, aber die hat vermutlich keine Eigenschaft url. Auch ist das egal, es zählt allein, an welchem Objekt das Callback gespeichert bzw. gerufen wird.
        Ich würde vermuten, das Callback wird mit den restlichen Optionen in einem Objekt gespeichert und dann wird an diesem das Callback gerufen. Das würde die Eigenschaft url erklären.
        Das wäre dann aber nicht dokumentiert und du kannst dich nicht darauf verlassen, daß das so bleibt.

        1. Moin

          Was ist »this« hier? Ich nehme an, $() ist jQuery und du wrappst ein Element damit. Dann wäre url eine Elementeigenschaft. Dann könntest du auch gleich »this.url« schreiben.

          $(this) bezieht sich auf das getJSON Objekt. Dies hat sehr wohl eine Eigenschaft URL.
          getJSON ist eine Funktion, gut auch das ist ein Objekt, aber die hat vermutlich keine Eigenschaft url. Auch ist das egal, es zählt allein, an welchem Objekt das Callback gespeichert bzw. gerufen wird.
          Ich würde vermuten, das Callback wird mit den restlichen Optionen in einem Objekt gespeichert und dann wird an diesem das Callback gerufen. Das würde die Eigenschaft url erklären.
          Das wäre dann aber nicht dokumentiert und du kannst dich nicht darauf verlassen, daß das so bleibt.

          Ergebnis der Ausgabe: $(this)

          accepts
          Object { *="*/*", text="text/plain", html="text/html", mehr...}

          async
          true

          contentType
          "application/x-www-form-urlencoded; charset=UTF-8"

          contents
          Object { xml=RegExp, html=RegExp, json=RegExp, mehr...}

          converters
          Object { text html=true, * text=String(), text json=function(), mehr...}

          crossDomain
          true

          dataType
          "json"

          dataTypes
          ["text", "json"]

          flatOptions
          Object { url=true, context=true}

          global
          true

          hasContent
          false

          isLocal
          false

          jsonp
          "callback"

          processData
          true

          responseFields
          Object { xml="responseXML", text="responseText", json="responseJSON"}

          type
          "GET"

          url
          "http://maps.googleapis....n&sensor=false"

          jsonpCallback
          function()

          xhr
          $c()

          das ist das normale XMLHTTPRequest-Objekt (bzw. jqXHR-Objekt) über das das Ajax abläuft. Sollte also funktionieren.

          Gruß Bobby

          --
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
          ### Henry L. Mencken ###
          -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
          ## Viktor Frankl ###
          ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
          1. das ist das normale XMLHTTPRequest-Objekt (bzw. jqXHR-Objekt) über das das Ajax abläuft. Sollte also funktionieren.

            Und wo steht, daß das jqXHR Objekt eine Eigenschaft url hat? Das habe ich nicht gefunden.
            Aber der Sinn des jqXHR Objektes ist ja folgender:

            For backward compatibility with XMLHttpRequest, a jqXHR object will expose the following properties and methods:

            readyState
               status
               statusText
               responseXML and/or responseText when the underlying request responded with xml and/or text, respectively
               setRequestHeader(name, value) which departs from the standard by replacing the old value with the new one rather than concatenating the new value to the old one
               getAllResponseHeaders()
               getResponseHeader()
               statusCode()
               abort()

            und genau das sehe ich nicht in deiner Ausgabe.

            1. Und wo steht, daß das jqXHR Objekt eine Eigenschaft url hat? Das habe ich nicht gefunden.

              Ein Fall von schlechter Dokumentation. Aus dem Code geht es hervor: Das Konfigurationsobjekt ist der Callback-Context, und das hat eine url-Eigenschaft.

              https://github.com/jquery/jquery/blob/2.1.0/src/ajax.js#L407-L410
              https://github.com/jquery/jquery/blob/2.1.0/src/ajax.js#L506-L507
              https://github.com/jquery/jquery/blob/2.1.0/src/ajax.js#L755-L756

              M.

              1. Und wo steht, daß das jqXHR Objekt eine Eigenschaft url hat? Das habe ich nicht gefunden.

                Ein Fall von schlechter Dokumentation. Aus dem Code geht es hervor: Das Konfigurationsobjekt ist der Callback-Context, und das hat eine url-Eigenschaft.

                Und selbst wenn es aus dem Code ersichtlich wäre, ist es nicht dokumentiert. Und was in einer API nicht dokumentiert ist, ist nicht für die Benutzung gedacht.
                Das ist ja das "Problem" von JS, jeder kann in den Code sehen und Internas echt zu kapseln macht eine Menge Arbeit.

                1. Moin

                  Und selbst wenn es aus dem Code ersichtlich wäre, ist es nicht dokumentiert. Und was in einer API nicht dokumentiert ist, ist nicht für die Benutzung gedacht.
                  Das ist ja das "Problem" von JS, jeder kann in den Code sehen und Internas echt zu kapseln macht eine Menge Arbeit.

                  Ja mag sein. Ich denke aber, dass in Zukunft nicht daran rungeschraubt wird. Und in der eingebundenen JQuery-Bibliothek schon gleich gar nicht. ;)

                  Aber trotzdem Dank für Eure Hinweise.

                  Gruß Bobby

                  --
                  -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
                  ### Henry L. Mencken ###
                  -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
                  ## Viktor Frankl ###
                  ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                2. Und selbst wenn es aus dem Code ersichtlich wäre, ist es nicht dokumentiert. Und was in einer API nicht dokumentiert ist, ist nicht für die Benutzung gedacht.

                  Es ist durchaus hier erwähnt, im Rahmen des context-Settings:
                  http://api.jquery.com/jQuery.ajax/

                  »context
                  Type: PlainObject
                  This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax). [Dann wird erklärt, wie man den Kontext selbst setzen kann.]«

                  Der Default-Fall ist auch durchaus getestet:
                  https://github.com/jquery/jquery/blob/2.1.0/test/unit/ajax.js#L409-L421

                  Und ich vermute, der Haupt-Anwendungsfall ist dieser hier:
                  https://github.com/jquery/jquery/blob/2.1.0/test/unit/ajax.js#L151-L183
                  Im Fehlerfall nimmt man die Settings und gibt sie einfach nochmal an jQuery.ajax().

                  Den context-Kram zumindest würde ich nicht als Interna bezeichnen.

                  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.

                  jQuery setzt an vielen Stellen this auf irgendein obskures Objekt. In fast allen Fällen würde ich davon abraten, es zu nutzen. Und meistens kann man es auch.

                  Bei der Objektorientierten Programmierung will man meist selbst this verwenden, um das aktuelle Objekt zu referenzieren. Dazu werden die Callback-Funktionen gebunden.

                  Stellen in jQuery, wo man this vermeiden sollte:

                  $('#foo').on('click', function(event) {  
                    alert(this); // Pfui  
                    alert(event.currentTarget); // Pendant  
                    alert(event.target); // Manchmal will man auch das  
                  });
                  
                  // Ja, das ist die Parameterreihenfolge! Bei Array#forEach,  
                  // Array#some usw. sowie in allen vernünftigen Sprachen und Bibliotheken ist sie umgekehrt.  
                  $('.foo').each(function(index, element) {  
                    alert(this); // Pfui  
                    alert(element); // Pendant  
                  });
                  

                  Hier kann man es dummerweise nicht vermeiden:

                  $('.foo').filter(function(index) {  
                    alert(this); // Das Elementobjekt  
                  });
                  

                  jQuery ist in dieser Hinsicht ziemlich kaputt.

                  </threaddrift>
                  Mathias

                  1. Es ist durchaus hier erwähnt, im Rahmen des context-Settings:
                    http://api.jquery.com/jQuery.ajax/

                    Den default context hatte ich eigentlich gesucht, aber nicht gefunden.
                    Dann nehme ich meine Bemerkung zurück, es ist also durchaus legitim hier auf die url Eigenschaft der Settings zuzugreifen.

                    1. Moin

                      Den default context hatte ich eigentlich gesucht, aber nicht gefunden.
                      Dann nehme ich meine Bemerkung zurück, es ist also durchaus legitim hier auf die url Eigenschaft der Settings zuzugreifen.

                      Nun bin ich aber froh, dass auch das geklärt ist, und meine Lösung sinnvoll und richtig ist (übrigens: siehe meiner Signatur). In diesem Sinne, Dank an Euch für die rege Diskussion. So ist dieses Forum effektiv!

                      Gruß Bobby

                      --
                      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
                      ### Henry L. Mencken ###
                      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
                      ## Viktor Frankl ###
                      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                      1. Om nah hoo pez nyeetz, Bobby!

                        (übrigens: siehe meine Signatur).

                        Ich find 11 auch viel schöner als 12.

                        Matthias

                        --
                        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen digital und Digitalis.

                        1. Moin

                          Ich find 11 auch viel schöner als 12.

                          Chat schöner als JS??? Mir erschließt sich dein Pot gerade nicht... :/

                          Gruß Bobby

                          --
                          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
                          ### Henry L. Mencken ###
                          -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
                          ## Viktor Frankl ###
                          ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                          1. Om nah hoo pez nyeetz, Bobby!

                            Ich find 11 auch viel schöner als 12.

                            Chat schöner als JS??? Mir erschließt sich dein Pot gerade nicht... :/

                            Zähl mal, was in deiner Signatur 11 mal vorkommt und möglicherweise eigentlich 12 mal vorkommen sollte. Schön, dass es dich trotzdem zum Grübeln anregte.

                            Matthias

                            --
                            Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Turm und Turmalin.

                            1. Moin

                              Zähl mal, was in deiner Signatur 11 mal vorkommt und möglicherweise eigentlich 12 mal vorkommen sollte. Schön, dass es dich trotzdem zum Grübeln anregte.

                              Na klar regt mich das zum nachdenken an. Ich reflektiere sehr oft die Anmerkungen anderer. Man lernt ja nie aus. ;)

                              Du sprichst in Rätseln... meintest du das fehlende "#"-Zeichen?

                              Gruß Bobby

                              --
                              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
                              ### Henry L. Mencken ###
                              -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
                              ## Viktor Frankl ###
                              ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                              1. Om nah hoo pez nyeetz, Bobby!

                                Du sprichst in Rätseln... meintest du das fehlende "#"-Zeichen?

                                Genau.

                                Matthias

                                --
                                Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Turm und Turmalin.

                          2. Hi,

                            Ich find 11 auch viel schöner als 12.
                            Chat schöner als JS???

                            Wenn, dann js schöner als mo.
                            Oder fängst Du etwa mit Index 1 an?

                            cu,
                            Andreas

                            --
                            Warum nennt sich Andreas hier MudGuard?
                            O o ostern ...
                            Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
                            1. Moin

                              Wenn, dann js schöner als mo.
                              Oder fängst Du etwa mit Index 1 an?

                              hihi.. ich hatte mal außerhalb des Informatikindex gedacht. Da fang ich mit 1 Apfel an und zähle dann weiter. Weil 0 Äpfel ja nix sind. In der Informatik hast du aber selbstverständlich recht. ;)

                              Gruß Bobby

                              --
                              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
                              ### Henry L. Mencken ###
                              -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
                              ### Viktor Frankl ###
                              ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
                  2. Und ich vermute, der Haupt-Anwendungsfall ist dieser hier:
                    https://github.com/jquery/jquery/blob/2.1.0/test/unit/ajax.js#L151-L183
                    Im Fehlerfall nimmt man die Settings und gibt sie einfach nochmal an jQuery.ajax().

                    Mag sein, aber intuitiv finde ich das nicht.

                    Den context-Kram zumindest würde ich nicht als Interna bezeichnen.

                    Wieso nicht? Wenn du meinst, daß es ja explizit in der Doku steht, gebe ich dir recht.
                    Sonst ist aber der context eines Callbacks von außen nicht ersichtlich, wenn man ihn nicht selbst von außen festlegt.

                    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? Die liegen (hier und im unittestfall) im Scope des Callbacks.

                    jQuery setzt an vielen Stellen this auf irgendein obskures Objekt.

                    Ja, gut, aber irgendwo müssen sie ihr Callback ja speichern. Wenn sie sich über das wo noch Gedanken machen und das auch dokumentieren finde ich das in Ordnung.
                    Ich hätte in diesem Fall nicht das Optionobjekt genommen, aber das ist nur meine Meinung.

                    In fast allen Fällen würde ich davon abraten, es zu nutzen.

                    Kommt darauf an, hier hätte ich es auch nicht verwendet. Hinzu kommt meistens auch noch deine nächste Bemerkung:

                    Bei der Objektorientierten Programmierung will man meist selbst this verwenden, um das aktuelle Objekt zu referenzieren.

                    Aber abraten, wenn der Defaultcontext definiert ist? Warum?

                    $('#foo').on('click', function(event) {

                    alert(this); // Pfui
                      alert(event.currentTarget); // Pendant
                      alert(event.target); // Manchmal will man auch das
                    });

                    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?  
                      
                    
                    > ~~~javascript
                    
                    // Ja, das ist die Parameterreihenfolge! Bei Array#forEach,  
                    
                    > // Array#some usw. sowie in allen vernünftigen Sprachen und Bibliotheken ist sie umgekehrt.  
                    > $('.foo').each(function(index, element) {  
                    >   alert(this); // Pfui  
                    >   alert(element); // Pendant  
                    > });
                    
                    

                    this ist element? Ja, daß finde ich auch merkwürdig, wie hier das Optionobjekt.

                    Hier kann man es dummerweise nicht vermeiden:

                    $('.foo').filter(function(index) {

                    alert(this); // Das Elementobjekt
                    });

                    Naja, vermeiden schon, du hast den index und ein Array. Aber hier steht es sogar wieder explizit in der Doku.  
                    Du hast aber recht, hier gehört das Element als Parameter an die Funktion.  
                      
                    
                    > jQuery ist in dieser Hinsicht ziemlich kaputt.  
                    
                    Was heißt kaputt? Soweit ich das jetzt sehe, haben die sich tatsächlich bei jedem Callback gedanken über den Context gemacht.  
                    Ich hatte ja anfangs vermutet, der ist hier zufällig das Optionobjekt geworden, weil sie das Callback zufällig an diesem gespeichetrt haben.  
                    Aber dein oben erwähnter Haupt-Anwendungsfall macht ja durchaus Sinn, auch wenn ich das nicht unbedingt schön finde.  
                    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.
                    
                    1. 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

                      1. Wie komm ich sonst daran?

                        Im einfachsten (und ich würde behaupten, das ist der Normalfall) so

                        obj = {  
                          loadData: function() {  
                            $.ajax({  
                              url: "meine_url",  
                              error: this.errHandler.bind(this)  
                            });  
                          },  
                          errHandler: function() {  
                            this.mfkt();  
                          }  
                        };
                        

                        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

                        Aber selbst wenn man die Settings erst generisch zusammenbasteln muss, sehe ich da kein Problem

                        obj = {  
                          mfkt: function() {  
                            var ajaxoptions;  
                          
                            ajaxoptions = {  
                              url: url("data/errorWithText.php"),  
                              error: this.errHandler().bind(this, ajaxoptions);  
                            };  
                            loadData(ajaxoptions);  
                          },  
                          loadData: function(ajaxoptions) {  
                            $.ajax(ajaxoptions);  
                          },  
                          err: function(ajaxoptions) {  
                            this.loadData(ajaxoptions);  
                          }  
                        };
                        

                        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.

                        Die Settings sind in der temporären Variablen {url:..., error:...} im Scope der anonymen Funktion, welche an asyncTest übergeben wird, gespeichert.
                        Eine Referenz auf dieses temporary wird der ajax-Funktion übergeben, welche es dann als Context des Errorhandlers bindet.
                        Dieser temporären Variablen noch ein deklaratives var zu verpassen macht es jetzt nicht komplexer.

                        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.

                        Aber dann habe ich die Parameter die ich an diese Funktionen übergebe und lasse es mir ein weiteres mal intern erzeugen.

                        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.

                        Das "Aber abraten, wenn der Defaultcontext definiert ist? Warum?" war hier nicht auf

                        Bei der Objektorientierten Programmierung will man meist selbst this verwenden, um das aktuelle Objekt zu referenzieren.

                        bezogen, dann ist es ja klar, dass man es nicht nutzen kann. War schlecht ersichtlich, gebe ich zu.

                        Der Kontext von Event-Handlern ist seit langem so in »DOM 0« (sprich seit Netscape 2.0) definiert.

                        Bei DOM 0 Event-Handlern ist der Context klar ersichtlich, ich selbst speichere ja den Eventhandler am element
                        element.onevent = function() { alert(this) }
                        Es wird also mit element.onevent() gerufen.
                        Bei addEventListener ist es definiert https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener#The_value_of_this_within_the_handler.
                        (Wobei ich die Beschreibung dort schon grenzwertig finde.)
                        Sinnvoller Weise kompatibel und jedes Framework muss es wiederum definieren.
                        Aber das Beispiel zeigt es doch ganz gut. jQuery hat sich hier auch für Kompatibilität entschieden. Das ist doch erst mal gut.

                        Ja, aber warum überhaupt? ... Man sollte es den Entwicklern überlassen, die auf Basis von jQuery High-Level-Anwendungen entwickeln.

                        Den Context bestimmt immer derjenige, welcher den Handler übergibt.
                        Nur wenn ihm dieser egal ist, bestimmt es das Framework, dann kann man diesen aber auch ignorieren.
                        Es sei denn, dieser, durch das Framework bestimmte Context, ist ein wichtiger Bestandteil, an den man anders nicht (vernünftig) herankommt. Wie in deinem letzten Beispiel.
                        Also dort fehlt das Element als Parameter, nicht der Defaultcontext als Element ist das Problem.
                        Diesen kann nutzen wer will, man sollte ihn aber nicht nutzen MÜSSEN.
                        Klar, wenn man von vornherein darauf verzichtet hätte hier einen Context sinnvoll zu setzen, wäre das aufgefallen.

            2. Und wo steht, daß das jqXHR Objekt eine Eigenschaft url hat? Das habe ich nicht gefunden.

              Sorry, du hast natürlich völlig Recht. jqXHR hat keine url-Eigenschaft, sondern das Konfigurationsobjekt. this zeigt nicht auf ein jqXHR-Objekt, sondern auf das Konfigurationsobjekt! Das jqXHR-Objekt wird als erster Parameter an den Callback übergeben.

      2. $(this) bezieht sich auf das getJSON Objekt. Dies hat sehr wohl eine Eigenschaft URL.

        this verweist auf das jqXHR-Objekt, das ist ein von jQuery erzeugtes Objekt. Ja, das hat eine url-Eigenschaft.

        Dann kannst du aber immer noch this.url schreiben. $(this)[0] gibt dir das, was du hineingibst, wieder zurück. $(123.456)[0] ergibt 123.456 usw.

        Wenn man einfach nur auf eine Eigenschaft eines simplen Objektes zugreifen will, das einem auch direkt vorliegt, braucht man nicht jQuery verwenden.

        var objekt = { foo: 'bar' };  
        alert(objekt.foo);
        

        Mathias