1UnitedPower: Datentypen in Javascript

Ich würde gerne einen Artikel über Datentypen in Javascript verfassen, der zum einen den Unterschied zwischen primitiven und komplexen Datentypen behandelt, und zum anderen gesondert auf die Unterschiede zwischen Primitiven und ihren komplexen Pendants (boolean vs. Boolean) eingeht. Ich weiß allerdings nicht wo ich ihn unterbringen sollte.

  1. Tach!

    Ich würde gerne einen Artikel über Datentypen in Javascript verfassen, der zum einen den Unterschied zwischen primitiven und komplexen Datentypen behandelt, und zum anderen gesondert auf die Unterschiede zwischen Primitiven und ihren komplexen Pendants (boolean vs. Boolean) eingeht. Ich weiß allerdings nicht wo ich ihn unterbringen sollte.

    Du meinst, etwas das zum Beispiel über das "Beachten Sie" am Anfang von http://wiki.selfhtml.org/wiki/Referenz:JavaScript/Boolean hinausgeht? Ansonsten vielleicht bei Sprachelemente - Variablen. Zum Üben empfiehlt sich erstmal der eigene Benutzernamensraum, Benutzer:Name und gegebenenfalls da auch Unterseiten à la Benutzer:Name/Unterseite.

    dedlfix.

    1. Du meinst, etwas das zum Beispiel über das "Beachten Sie" am Anfang von http://wiki.selfhtml.org/wiki/Referenz:JavaScript/Boolean hinausgeht?

      Genau, ich möchte mehr ins Detail gehen.

      Ansonsten vielleicht bei Sprachelemente - Variablen. Zum Üben empfiehlt sich erstmal der eigene Benutzernamensraum, Benutzer:Name und gegebenenfalls da auch Unterseiten à la Benutzer:Name/Unterseite.

      Gute Idee! Dort werde ich beginnen.

  2. Hallo,

    Ich würde gerne einen Artikel über Datentypen in Javascript verfassen, der zum einen den Unterschied zwischen primitiven und komplexen Datentypen behandelt, und zum anderen gesondert auf die Unterschiede zwischen Primitiven und ihren komplexen Pendants (boolean vs. Boolean) eingeht.

    Ich bin ja immer geneigt, die »boxed primitives« möglichst zu verschweigen. ;) Denn die einzige praktisch nützliche Info ist, sie zu vermeiden. Einen triftigen Grund, warum JavaScript boxed primitives hat, gibt es nicht.

    Spannend wird das Thema, wenn man beliebigen Objekten mit valueOf und toString die Möglichkeit gibt, ihre Umwandlung in Primitives zu bestimmen. toJSON fällt auch in diese Kategorie. Aber das braucht man in zehn Jahren vielleicht einmal.

    Viele Grüße,
    Mathias

    1. Ich bin ja immer geneigt, die »boxed primitives« möglichst zu verschweigen. ;) Denn die einzige praktisch nützliche Info ist, sie zu vermeiden. Einen triftigen Grund, warum JavaScript boxed primitives hat, gibt es nicht.

      Ich bin im wesentlichen deiner Meinung, allerdings lassen sich über die Prototypen Methoden hinzufügen. Ein nützliches Anwendungsbeispiel will mir aber auch partout nicht einfallen.

      primitives Beispiel

      Spannend wird das Thema, wenn man beliebigen Objekten mit valueOf und toString die Möglichkeit gibt, ihre Umwandlung in Primitives zu bestimmen. toJSON fällt auch in diese Kategorie. Aber das braucht man in zehn Jahren vielleicht einmal.

      Gab es nicht mal eine jQuery-Version, die ihren Selektor bei toString() zurückgeben hat? Fand das scheußlich, weil es die Lesbarkeit auf so viele Arten verschlechtert hat.

      1. Gab es nicht mal eine jQuery-Version, die ihren Selektor bei toString() zurückgeben hat? Fand das scheußlich, weil es die Lesbarkeit auf so viele Arten verschlechtert hat.

        Ich erinnere mich, dass mal sowas möglich war:

          
          
        var foo = $('.foo');  
          
        $( foo+':not(".bar")').each( function(){ /* some code */});  
          
        
        
        1. Ich erinnere mich, dass mal sowas möglich war:

          var foo = $('.foo');
          $( foo+':not(".bar")').each( function(){ /* some code */});

            
          Den Selektor kriegt man derzeit über `$('.foo').selector`{:.language-javascript} heraus. Mit toString zu arbeiten wäre wirklich verwirrend im Falle von jQuery-Objekten. Ansonsten finde ich toString fürs Debugging ziemlich nützlich.  
            
          Den obigen Fall kann man besser so lösen (wenn es nicht direkt in einer Operation geht):  
            
          `$('.foo').filter(':not(.bar)')`{:.language-javascript}  
            
          Grüße,  
          Mathias
          
          1. var foo = $('.foo');
            $( foo+':not(".bar")').each( function(){ /* some code */});

              
            
            > Den obigen Fall kann man besser so lösen (wenn es nicht direkt in einer Operation geht):  
            >   
            > `$('.foo').filter(':not(.bar)')`{:.language-javascript}  
              
            Und das sollte man auch. Ich habe es nur als Fallbeispiel angeführt, bei dem der Nutzen einer benutzerdefinierten toString-Methode die Leserlichkeit verschlechtert. 
            
      2. Ich bin im wesentlichen deiner Meinung, allerdings lassen sich über die Prototypen Methoden hinzufügen.

        Gut, das ist für mich ein anderes Thema. Auf »new Boolean« kommt man normalerweise nicht, aber man kann darauf über diesen Umweg kommen:

        1. Man beschäftigt sich mit Kerntypen, deren Konstruktoren und Prototypen.
        2. So stößt man auf die Konstruktoren Boolean, Number, String sowie deren prototype-Eigenschaften.
        3. Jetzt kann man sich fragen, was passiert, wenn man sie mit »new« aufruft. Erst jetzt muss man den Unterschied zwischen Primitives und Boxed Primitives verstehen.

        Die Unterscheidung zwischen Primitives und Objects ist natürlich allgemeiner, da hatte ich auch mal was angefangen:
        http://molily.de/js/kernobjekte.html#objects-primitives

        Ein nützliches Anwendungsbeispiel will mir aber auch partout nicht einfallen.

        PrototypeJS, Mootools und SugarJS machen das sehr extensiv.

        Mathias

  3. der zum einen den Unterschied zwischen primitiven und komplexen Datentypen behandelt,

    Wo siehst du dort einen speziellen Unterschied? Ausser dem offensichtlichen Unterschied, dass ein komplexer Datentyp primitive (und auch komplexe) Daten als Member hat. Das ist ja aber keine JS-Spezialität.

    und zum anderen gesondert auf die Unterschiede zwischen Primitiven und ihren komplexen Pendants (boolean vs. Boolean) eingeht.

    Wo gibt es in JS ein boolean? Mit den primitiven Repräsentationen kommt man in JS ja überhaupt nicht in Berührung (ausser in der Schreibweise, wenn man so will). Aber hinter einem einfachem true/false steht auch ein Boolean-Objekt.

    1. der zum einen den Unterschied zwischen primitiven und komplexen Datentypen behandelt,
      Wo siehst du dort einen speziellen Unterschied? Ausser dem offensichtlichen Unterschied, dass ein komplexer Datentyp primitive (und auch komplexe) Daten als Member hat. Das ist ja aber keine JS-Spezialität.

      und zum anderen gesondert auf die Unterschiede zwischen Primitiven und ihren komplexen Pendants (boolean vs. Boolean) eingeht.
      Wo gibt es in JS ein boolean? Mit den primitiven Repräsentationen kommt man in JS ja überhaupt nicht in Berührung (ausser in der Schreibweise, wenn man so will). Aber hinter einem einfachem true/false steht auch ein Boolean-Objekt.

      Du hast mich eventuell missverstanden. Ich möchte keine Gegenüberstellung verfassen, sondern einen rein informativen Artikel schreiben. á la:

      • Es gibt primitive und komplexe Typen
      • Wie erhalte ich den primitiven und wie den komplexen Typen eines Wertes
      • Was sind boxed primitives?
      • Was kann ich damit anstellen? Was besser nicht?
      • Was ist truly und falsy?
      • Warum evaluiert new Boolean(false) zu truly?
      • Warum gibt es überhaupt null und undefined?
      • etc.

      Ich werde den Artikel, wie von dedlfix vorgeschlagen, erstmal in meinem eigenen Benutzernamensraum anlegen. Ob er am Ende einen praktischen Nutzen für das Wiki hat, oder nur von Trivia handelt, die keiner näheren Einführung bedürfen, wird sich am Ende zeigen.

    2. Hallo,

      Wo gibt es in JS ein boolean? Mit den primitiven Repräsentationen kommt man in JS ja überhaupt nicht in Berührung (ausser in der Schreibweise, wenn man so will).

      Es gibt verschiedene Sprachfeatures, die nur durch die Unterscheidung zwischen Primitives und Objekten erklärt werden können. Objekte haben Identität, sind also nur selbstidentisch (obj === obj) und nicht identisch mit anderen Objekten. Primitives können mit anderen Primitives identisch sein ("foo" === "foo"). Es gibt definierte Wege, wie Objekte in Primitives umgewandelt werden (intern ToPrimitive, nach außen valueOf bzw. toString). Objekte werden per Referenz übergeben (bzw. by sharing), Primitives werden kopiert.

      Aber hinter einem einfachem true/false steht auch ein Boolean-Objekt.

      Jein. Erst in einem Kontext, der ein Objekt verlangt, werden sie in Objekte umgewandelt. Z.B. beim Property-Accessor-Operator.

      Natürlich optimieren das die Engines ggf. weg, aber so ist es in der ECMAScript-Spezifikation definiert.

      Mathias

      1. Aber hinter einem einfachem true/false steht auch ein Boolean-Objekt.
        Erst in einem Kontext, der ein Objekt verlangt, werden sie in Objekte umgewandelt. Z.B. beim Property-Accessor-Operator.

        Wichtig ist, dass diese Umwandlung nicht den ursprünglichen Primitive ändert und man üblicherweise keine Referenz auf das erzeugte Objekt erhält.

        var bool = false;  
        bool.member = "wtf";  
        alert(bool.member); // undefined
        

        Dieses Verhalten lässt sich nicht erklären, wenn man nicht zwischen Primitives und Objects unterscheidet und alles als Object ansieht.

        Was hier passiert ist:

        Object(bool).member = "wtf";  
        alert(Object(bool).member); // undefined
        

        Bei diesen beiden Umwandlungen in ein Object kommt ein anderes Objekt heraus. Das erste wird erweitert, dann aber weggeworfen.

        Mathias

        1. Immer schön von dir zu lesen. Ich schätze ich brauch noch Übung, um mich so präzise ausdrücken zu können.

      2. Es gibt verschiedene Sprachfeatures, die nur durch die Unterscheidung zwischen Primitives und Objekten erklärt werden können.

        Natürlich gibt es die, bestes Beispiel typeof, aber im normalen Umgang merkt man diesen nicht - ok, kaum. Alle Memberfunktionen der Objekte ändern nie das Objekt selber, sondern geben das Ergebniss immer als Returnwert zurück.

        Objekte werden per Referenz übergeben (bzw. by sharing), Primitives werden kopiert.

        Auch bei der Übergabe an Funktionen merkt man es nicht. Du schreibst erst Objekte werden per Referenz übergeben und Primitives werden kopiert, verlinkst dann aber auf einen Artikel wo eigentlich steht, dass beide, Objekte und Primitives, kopiert werden.

        Objekte haben Identität, sind also nur selbstidentisch (obj === obj) und nicht identisch mit anderen Objekten. Primitives können mit anderen Primitives identisch sein ("foo" === "foo").

        Ja, bei Operatoren die auf Identität prüfen gibt es Unterschiede.
        Auch bei deinem nächsten Beispiel, dem temporary beim cast, merkt man den Unterschied, wobei das Beispiel schon ziemlich konstruiert ist.