if (new MyObject()) mit Boole'sch falschen Ergebnis
Cheatah
- javascript
Hi,
ich speichere ein selbst erstelltes Objekt, welches bestimmte Methoden vorhalten soll. Es resultiert aus Prüfungen, die entweder "nichts" oder "ein Objekt mit bestimmten Werten" ergeben.
Um Abfragen auf das Objekt möglichstleicht zu gestalten, habe ich im Falle "nichts" bisher einen leeren String zurück geliefert. Dieser ist ein vollwertiges Objekt, so dass "foo['bar']" keinen Fehler erzeugt, liefert aber bei "if (foo)" false zurück (sinngemäß). Nun erweitere ich das "echte" Objekt aber um einige Methoden, um "if (foo.qaz('bar'))" erfragen zu können. Da ich nun das String-Objekt nicht um die selben Methoden erweitern möchte (die da nämlich eigentlich nichts verloren haben -- oder eventuell sogar anderweitig benötigt werden), versuche ich ein Objekt zu schaffen, welches bei einem "if (foo)" ebenso reagiert (wird), wie es bei einem Leerstring der Fall ist.
Leider sind meine Recherchen und Versuche bisher erfolglos. Von String erben zu lassen brachte nichts, Rückgaben in toString()- und valueOf()-Methoden bewirken nicht das Gewünschte (egal ob ein Leerstring, false, null oder undefined geliefert wird), nicht einmal ein "return false;" direkt im Constructor brachte Erfolg :-) Wie also bringe ich einem Objekt bei, "falsch zu sein"?
Zur Verdeutlichung noch mal ein Dummy-Code:
var x = 42 ? new RealObject() : new FalseObject();
var y = 0 ? new RealObject() : new FalseObject();
...
if (x && x.foo && x.bar()) { /* Soll ausgeführt werden */ }
if (y || y.foo || y.bar()) { /* Soll nicht ausgeführt werden */ }
Cheatah
Hallo !
hab das jetzt so verstanden, dass statt des neuen "FalseObject()"
var y = 0 ? new RealObject() : new FalseObject();
das bislang so implemeniert waere :
var y = 0 ? new RealObject() : "" ;
Ist das richtig ?
Denn
"foo['bar']" keinen Fehler erzeugt,
Also bei mir schon, wenn foo ein Leerstring ist...
liefert aber bei "if (foo)" false
Also bei mir gibt's true, wohl da foo zwar leer aber nicht null ist...
Dann
if (y || y.foo || y.bar()) { /* Soll nicht ausgeführt werden */ }
versteh ich die ORs ('||') nicht. Gaebe Dein Objekt false zurueck, wuerden grade durch die ORs naemlich die undefinierten Funktionen ins Spiel kommen.
Warum nicht so ( mal abgesehen davon, dass y != false )
if (y && y.foo y x.bar()) { /* Soll ausgeführt werden */ }
Unter C++ macht man sowas mit einem "Ueberladenen Cast-Operator" ( genauer koennte, tut es aber besser nicht); vielleicht hilft der Begriff ja beim Googlen.
Darf ich anmerken, dass ich den Entwurf fuer recht ueberdenkenswert halte; einfach null zuruckgeben und mit and ( && ) pruefen bringt es doch schon.
Gruss
Holger
Hi,
hab das jetzt so verstanden, dass statt des neuen "FalseObject()"
das bislang so implemeniert waere :var y = 0 ? new RealObject() : "" ;
Ist das richtig ?
ja.
Denn
"foo['bar']" keinen Fehler erzeugt,
Also bei mir schon, wenn foo ein Leerstring ist...
Echt? In welchem Browser? Ein <javascript:alert(""['bar'>)] sollte eigentlich ohn' Sorg sein.
liefert aber bei "if (foo)" false
Also bei mir gibt's true, wohl da foo zwar leer aber nicht null ist...
<javascript:if ("") alert(0); else alert(1);> ergibt 1.
Dann
if (y || y.foo || y.bar()) { /* Soll nicht ausgeführt werden */ }
versteh ich die ORs ('||') nicht. Gaebe Dein Objekt false zurueck, wuerden grade durch die ORs naemlich die undefinierten Funktionen ins Spiel kommen.
Die natürlich ihrerseits undefined liefern :-)
Warum nicht so ( mal abgesehen davon, dass y != false )
if (y && y.foo y x.bar()) { /* Soll ausgeführt werden */ }
Weil bereits ein "if (y)" nicht ausgeführt werden soll. Die Veroderung hatte ich gewählt, um klar zu machen, dass keine der Varianten positiv ausfallen soll. Tut mir leid, dass Dich gerade das verwirrt hat :-)
Unter C++ macht man sowas mit einem "Ueberladenen Cast-Operator" ( genauer koennte, tut es aber besser nicht); vielleicht hilft der Begriff ja beim Googlen.
Ich glaube nicht, dass ich damit jetzt erfolgreicher bin als vorhin ;-)
Darf ich anmerken, dass ich den Entwurf fuer recht ueberdenkenswert halte; einfach null zuruckgeben und mit and ( && ) pruefen bringt es doch schon.
Ich baue ein Singleton-Objekt, das als Informationsquelle dienen soll, die von Dutzenden von Entwicklern verwendet werden wird, von denen einige JavaScript noch mit Java verwechseln. Es ist in der Praxis nicht durchführbar, diesen die Pflicht aufzuerlegen, alle Eventualitäten abzuprüfen - sie werden es einfach nicht tun. Statt dessen wird es sinngemäße "if (null.bar('qaz'))" geben, die nicht bemerkt werden, weil eben diese Leute dummerweise an der QS vorbei entwickeln. Nein, zumindest bei Verwendung der dokumentierten Schnittstelle muss das ganze narrensicher sein, _ohne_ dass nachgedacht werden muss[1].
Cheatah
P.S.: Die JavaScript-Links bitte bei Bedarf manuell in den Browser kopieren ...
[1] Ähm, das ist natürlich eine Tautologie :-)
Hallo !
Hab die Snippets nicht im Broweser, sondern auf der Kommandozeile mit
NGS JavaScript Interpter 0.2.5
ausgefuehrt.
Offenbar prueft der strenger als der Browser die Du verwendest.
Koennte natuerlich auch ein Bug sein - waer schon ein starker Stueck wenn DAS ( also Core-Sprachmerkmal ) zwischen Implementierungen abweichen duerfte. ( Fuer mich persoenlich momentan aber nicht wirklich wichtig )
Ich glaube nicht, dass ich damit jetzt erfolgreicher bin als vorhin ;-)
Wie man's nimmt..
Also ich weiss, dass ich mir damit eben das gegoogled habe :
"JavaScript does not have a cast operator, a mechanism often used in C, C++, and Java to convert values from one type to another. To force a conversion in JavaScript, you must generally invoke a function or method."
Also - ein wie auch immer implementierter - impliziter "cast" auf false geht nicht. Genau das braeuchtest Du aber.
Ich baue ein Singleton-Objekt, das als Informationsquelle dienen soll, die von Dutzenden von Entwicklern verwendet werden wird, von denen einige JavaScript noch mit Java verwechseln.
» Es ist in der Praxis nicht durchführbar, diesen die Pflicht aufzuerlegen, alle Eventualitäten abzuprüfen - sie werden es einfach nicht tun.
Ein wenig erinert mich das trotzdem die Quadratur des Kreises. Imo reicht ganz einfach der Sprachumfang von js dafuer nicht aus.
Gruss
Holger
Hi,
Hab die Snippets nicht im Broweser, sondern auf der Kommandozeile mit
NGS JavaScript Interpter 0.2.5
ausgefuehrt.
Offenbar prueft der strenger als der Browser die Du verwendest.
oder falscher :-) wie die Website an sich vermuten lässt: Die Bugzilla-Instanz ist nicht richtig eingerichtet, die meisten Doku-Links gehen auf eine Site, die vor Jahren abgeschaltet wurde ... Ehrlich gesagt würde ich in die Software nicht allzu viel Vertrauen setzen. Zumal es IMHO sehr klar ist, dass ein String-Objekt wie z.B. "" ebenso wie jedes andere JavaScript-Objekt funktioniert, also z.B. Zugriffe auf nicht existente Eigenschaften einfach undefined liefern, keinen Fehler.
Ich glaube nicht, dass ich damit jetzt erfolgreicher bin als vorhin ;-)
Wie man's nimmt..
Also ich weiss, dass ich mir damit eben das gegoogled habe :
Ja, eben, das ist für mich nicht erfolgreich :-)
Also - ein wie auch immer implementierter - impliziter "cast" auf false geht nicht. Genau das braeuchtest Du aber.
Richtig. Da dies (oder etwas Entsprechendes - was zu finden ich versuche) augenscheinlich beim String-Objekt funktioniert, halte ich ein Aufgeben an dieser Stelle für verfrüht.
Ich baue ein Singleton-Objekt, das [...]
Ein wenig erinert mich das trotzdem die Quadratur des Kreises. Imo reicht ganz einfach der Sprachumfang von js dafuer nicht aus.
Naja, das Problem hatte ich bisher halt recht einfach über einen Leerstring gelöst. Da ich dem String-Prototype nicht haufenweise Methoden zuführen will, die es eigentlich nicht braucht, möchte ich im Grunde nur "das gleiche wie String in einem eigenen Objekt" haben. Das ist üblicherweise vergleichsweise einfach in JavaScript zu lösen, nur hakt es hier halt an einem Detail ...
Wie auch immer, ich danke Dir jedenfalls für Deine Mühen!
Cheatah