peterS.: schwache typisierung und typ-konvertierung, Objekte und Werte

Beitrag lesen

gruss Raik,

...
Das brachte mich zu folgendem Versuch:
...

javascript ist nur lose typisiert;

jeder js-interpreter wertet den typ eines datums auch abhaengig
   von dessen umgebung aus;

Dein beispiel nimmt sich den konstruktor Boolean vor, "gefuettert"
   wird er mit argumenten jeweils unterschiedlichen typs;

boolean-objekte koennen aber nur die werte false bzw. true
   einnehmen - der konstruktor bewertet die argumente dahingehend;

ohne argument oder mit einem undefinierten argument wird der
   konstruktor immer den wert false liefern, aber auch die argumente
   0, null und "" werden dahingehend ausgewertet - schon der einsatz
   jeden anderen wertes, und sei es z.b. "0" liefert ein boolean-objekt
   mit dem wert true zurueck;

fuer Dein gegebenes beispiel bedeutet dies, dass Deine variablen
   d1, d2, d3 bzw. d4 boolean-objekte jeweils mit dem wert false sind -
   Du trittst also bei deren spaeteren einsatz immer mit deren false-
   werten an, die Du dann auf die werte null, false und 0 vergleichst:

d1: (false == null)  // false;
   d2: (false == false) // true;
   d3: (false == 0)     // true;

d4: (false == 0)     // true; (das hatten wir grade)
   d4: (false == false) // true; (kurz davor dies auch)
   d4: (false == null)  // false;( ... siehe oben ... )

a) ein null-wert bleibt auch im kontext eines boolean-wertes null;
   b) boolean-werte koennen problemlos miteinander verglichen werden;
   c) der wert 0 vom typ number konvertiert im kontext eines boolean-wertes zu false;
   d) der wert "" vom typ string konvertiert im kontext eines boolean-wertes zu false;

nach dieser ausfuehrung mag es verwirren, warum fuer
   den auf den ersten blick eindeutigen fall von:

d1:false, d2:false, d3:false, d4:false

nun nicht (d1==d2==d3==d4) gleich true gelten soll,
   obwohl (false==false) gleich true ja offensichtlich gilt.

an dieser stelle stolperst Du ueber das problem, objekte aber nicht
   deren werte miteinander zu vergleichen, denn Du hast den Boolean-
   konstruktor einem einfachen boolean-literal vorgezogen - der beweis:

var d5=false, d6=false, d7=new Boolean(), d8=new Boolean();
   alert(typeof(d5)) // boolean;
   alert(typeof(d6)) // boolean;
   alert(typeof(d7)) // object;
   alert(typeof(d8)) // object;

alert(d5 == d6)   // true;
   alert(d5 == d8)   // true;
   alert(d6 == d7)   // true;
   //ABER:
   alert(d7 == d8)   // false;

Du kannst d5 und d6 untereinander, beide aber auch mit d7 bzw. d8
   vergleichen, da die werte d5 und d6 beim vergleich mit den objekten
   d7 und d8 den kontext fuer eine typenkonvertierung bieten - objekte
   hingegen lassen sich weder mit dem gleichheits[==] - noch mit dem
   identitaets[===]-operator vergleichen, dazu beduerfte es der noch
   zu schreibenden prototypen methode "Object.equals";

in diesem fall kann man aber auch abhilfe schaffen, indem man die
   fuer objekte eingebaute methode "toString" auf die boolean-objekte
   wie folgt anwendet:

alert(d7.toString());
   alert(d8.toString());
   alert(d7.toString()==d8.toString());

fazit:
   * das von Dir beschriebene verhalten ist ein grundsaetzliches;
   * jetzt ist es vielleicht verstaendlicher, warum ich in meinen
     ausfuehrungen so auf typ, wert und objekt herumgeritten bin;

regeln:
   * die "primitiven" typen boolean, number und string kommen als
     solche nur ueber ihre literalschreibweise zur anwendung:

var bool = true;
     var num = 123;
     var str = "hi";

* konstruktoren erzeugen objekte, denen werte zugewiesen sind:
     new Boolean(), new String() und new Number() sind nicht
     "primitiv" im sinne der ersten regel (und eigentlich gibt es
     diese terminologie in javascript auch ueberhaupt nicht [aber
     trotzdem wird der typeof-operator sehr oft bemueht]);

* besondere aufmerksamkeit sollte man den einfachen vergleichen
     [==] auf 0, null und "" widmen - typenkonvertierung verhindert
     hier nur der identitaetsoperator[===]; im gleichen zusammenhang
     ist auch darauf zu achten, dass jegliche pruefung auf die existenz
     von objekten fehlschlaegt "if (myObject) {...}", wenn diese einen
     der obigen werte haben; der "if"-block wird nie abgearbeitet,
     obschon es ein definiertes "myObject" gibt;

* gute type-detection ist die grundlage fuer eine schnelle und
     fehlerfreie entwicklung in schwach typisierten sprachen wie
     javascript:
     http://www.pseliger.de/jsExtendedApi/jsApi.Object.typeDetection.dev.js
     http://www.pseliger.de/jsExtendedApi/jsApi.Object.typeDetection.js

credits:
   * vor einem jahr las ich http://www.crockford.com/javascript/remedial.html,
     sodass Douglas Crockford in dieser hinsicht als mein lehrmeister betrachtet
     werden kann;

gute nacht fuer mich - guten morgen fuer Euch - peterS. - pseliger@gmx.net

--
sh:| fo:) ch:? rl:| br:& n3:} n4:# ie:| mo:{ va:| de:[ zu:] fl:) ss:) ls:& js:)