JavaScript Typsystem
Rolf b
- javascript
- selfhtml
0 Matthias Scharwies0 Rolf b
0 Orlok0 Rolf b
Hallo,
ich bin im Javascript-Teil gerade darüber gestolpert, dass nicht zwischen primitiven Typen und Wrappertypen unterschieden wird. Im Artikel zu Boolean wurde munter mit new Boolean() hantiert, obwohl das nun überhaupt keinen primitiven Boolean-Typ erzeugt, sondern einen Wrapper dazu. Das kann zu bösen Fehlern führen, ein Beispiel dafür habe ich dort nun angeführt.
Bevor ich als "Neuling" hier eine Baustelle aufmache und umbaue (würde ich gern übernehmen), hätte ich gern die Meinung der "altgedienten" dazu - ist das dort so Absicht gewesen oder war dieser Unterschied einfach nicht so ganz klar?
Obwohl - "Neuling" - das ist so GANZ richtig nicht, ich nutze SelfHTML seit vielen Jahren :)
Rolf
Hallo Rolf,
ich bin im Javascript-Teil gerade darüber gestolpert, dass nicht zwischen primitiven Typen und Wrappertypen unterschieden wird. Im Artikel zu Boolean wurde munter mit new Boolean() hantiert, obwohl das nun überhaupt keinen primitiven Boolean-Typ erzeugt, sondern einen Wrapper dazu. Das kann zu bösen Fehlern führen, ein Beispiel dafür habe ich dort nun angeführt.
Vielen Dank für Deine Initiative.
Bevor ich als "Neuling" hier eine Baustelle aufmache und umbaue (würde ich gern übernehmen), hätte ich gern die Meinung der "altgedienten" dazu - ist das dort so Absicht gewesen oder war dieser Unterschied einfach nicht so ganz klar?
Die JavaScript-Doku ist in (großen) Teilen noch eine Textübertragung aus der alten 8.12, in der der Schwerpunkt eher auf HTML und CSS lag.
und umbaue (würde ich gern übernehmen)
Vielen Dank im Voraus! Wir können wirklich viel Hilfe gebrauchen! Einige Sachen wie die Events haben wir bereits berichtigt (früher waren es HTML-Attribute, dann wanderten sie zu JavaScript und verloren das on-), die meisten Lücken gefült, aber es gibt noch viel zu tun.
Obwohl - "Neuling" - das ist so GANZ richtig nicht, ich nutze SelfHTML seit vielen Jahren :)
Das ist das Gute am Wiki, dass jetzt jeder mitmachen kann!
Herzliche Grüße
Matthias Scharwies
Hallo Matthias,
danke für die Einladung. Dass jeder mitmachen kann, muss ja nicht heißen, dass sich jeder beliebig austoben sollte. Es gibt ja sicherlich eine Linie, der ihr folgt. :)
Die Events sind übrigens auch heute noch eine spezielle Hölle für sich. Da darf man die Vergangenheit nicht einfach rauslöschen, damit Leute, die alten Code vor der Nase haben, dazu noch etwas nachlesen können. Ohne Frameworks wie jQuery lässt man von Events besser die Finger. Sind Verweise auf solche Bibliotheken hier statthaft?
Das Typsystem nehme ich mir dann mal vor. Hoffentlich gibt's da keine Besonderheiten pro Brauser.
Rolf
Hallo Rolf
ich bin im Javascript-Teil gerade darüber gestolpert, dass nicht zwischen primitiven Typen und Wrappertypen unterschieden wird. Im Artikel zu Boolean wurde munter mit new Boolean() hantiert, obwohl das nun überhaupt keinen primitiven Boolean-Typ erzeugt, sondern einen Wrapper dazu. Das kann zu bösen Fehlern führen, ein Beispiel dafür habe ich dort nun angeführt.
Bevor ich als "Neuling" hier eine Baustelle aufmache und umbaue (würde ich gern übernehmen), hätte ich gern die Meinung der "altgedienten" dazu - ist das dort so Absicht gewesen oder war dieser Unterschied einfach nicht so ganz klar?
Der Artikel von dem du hier offenbar sprichst ist unter Standardobjekte einsortiert, das heißt, der Gegenstand dieses Artikels ist grundsätzlich zunächst einmal der eingebaute Konstruktor Boolean
.
Bei einem Aufruf von Boolean
wird als erstes die interne Operation ToBoolean mit dem Wert des Funktionsparameters durchgeführt, die abhängig davon, ob es sich um einen truthy value oder um einen falsy value handelt, den primitiven Wert true
oder false
zurückgibt. Bei einem normalen Aufruf ist dieser Wert auch der Rückgabewert von Boolean
.
In diesem Fall wird also eine Typumwandlung durchgeführt:
const log = console.log.bind(console);
const foo = Boolean({ });
log(typeof foo); // boolean
log(foo); // true
const bar = Boolean(null);
log(typeof bar); // boolean
log(bar); // false
Wurde Boolean
hingegen mittels des Operators new
als Konstruktor aufgerufen, dann wird ein Objekt erzeugt, in dessen interner Eigenschaft [[BooleanData]]
der zuvor von ToBoolean
zurückgegebene primitive Wert hinterlegt wird.
Es wird also wie du sagst ein Wrapper Object erzeugt:
const log = console.log.bind(console);
const object = new Boolean([ ]);
log(typeof object); // object
const value = object.valueOf( );
log(typeof value); // boolean
log(value); // true
const string = object.toString( );
log(typeof string); // string
log(string); // true
Wird ein Objekt vom Typ Boolean erzeugt, dann erbt es von Boolean.prototype
die Methoden valueOf
und toString
, welche die gleichnamigen Methoden von Object.prototype
innerhalb der Prototypenkette verschatten.
Die Methode valueOf
kann verwendet werden um den Wert der internen Eigenschaft [[BooleanData]]
des Instanzobjektes zu examinieren und toString
erzeugt eine Stringrepräsentation dieses Wertes.
Also, lange Rede kurzer Sinn, ich denke das sollte in etwa der rote Faden der Story sein. Davon abgesehen stimme ich dir voll und ganz zu, dass der Unterschied von primitiven Datentyp Boolean und dem Objekttyp Boolean möglichst klar kommuniziert werden sollte …
… und ich würde mich sehr darüber freuen, wenn du diesen Artikel übernehmen würdest! :-)
Vielen Dank und viele Grüße,
Orlok
Hallo Orlok,
sehr interessanter Einblick, und gottlob war mir das nicht unbekannt sonst wäre ich jetzt rückwärts vom Stuhl gekippt. Der Wiki-Artikel muss (a) das Kippen vermeiden und sollte (b) trotzdem deine Infos transportieren. Naja, auf JavaScript-Engine Sourcecode-Ebene vielleicht nicht :)
Was deine Logs oben nicht zeigen, ist, dass "new Boolean(true) === true" false ergibt, d.h. das gewrappte Objekt ist nicht identisch mit dem primitiven Wert. Und dass new Boolean(false) truthy ist, ist einfach gruselig...
Was man in den Artikeln auch schreiben muss, ist, dass der Gebrauch der Wrapper die Ausnahme ist und nicht der Normalfall. Zu sagen, dass man new Boolean(true) hauptsächlich verwendet, um Rückgabewerte für Funktionen zu liefern, halte ich für schlicht falsch.
Mal gucken wie ich hinkomme, ohne den Artikel in Boolean(Objekt) und Boolean(primitiv) zu teilen. Das wäre wohl die schlechteste Lösung.
Rolf