var: Nihil privativum oder nihil negativum?

Hallo miteinander!

Ich bin gerade etwas verwirrt ob der Bedeutung der Zahl 0 in JavaScript: Bislang dachte ich immer, dass 0 in jedem Fall 0 ist, nicht aber null! ;-)

Wenn ich jedoch in einer Funktion einen Parameter ( n ) habe und diese Funktion mit dem Wert 0 für diesen Parameter aufrufe, dann ergibt ( !n ) gleich true!

Das sollte eigentlich nicht sein, oder? Ich meine, dafür gibt es ja das reservierte Wort null als speziellen Null-Wert. 0 sollte also 0 sein, aber nicht null!

Irgendwie nicht wirklich logisch, oder? ;-)

Gruß

var

  1. @@var:

    nuqneH

    Ich bin gerade etwas verwirrt ob der Bedeutung der Zahl 0 in JavaScript: Bislang dachte ich immer, dass 0 in jedem Fall 0 ist, nicht aber null! ;-)

    Ist es auch nicht.

    Wenn ich jedoch in einer Funktion einen Parameter ( n ) habe und diese Funktion mit dem Wert 0 für diesen Parameter aufrufe, dann ergibt ( !n ) gleich true!

    Das sollte eigentlich nicht sein, oder?

    Doch.

    “Everything in JavaScript has an inherent Boolean value, generally known as either truthy or falsy”

    http://www.sitepoint.com/javascript-truthy-falsy/

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    1. nuqneH

      Hallo Gunnar

      “Everything in JavaScript has an inherent Boolean value, generally known as either truthy or falsy”

      Das ist unbestritten. ;-)

      Die Frage ist nur, weshalb 0 in der Liste der "falsy values" stehen muss oder sollte, wenn wir schon den speziellen Null-Wert null haben.

      Finde, dass 0 per default einfach 0 sein sollte und wenn jemand zur Falsifizierung auf 0 oder 1 ( oder n > 0 ) zurückgreifen will, kann er oder sie das dann ja explizit bestimmen.

      So muss ICH explizit bestimmen, dass 0 !== false ist und ich würde schätzen, dass in der Mehrheit der Anwendungsfälle 0 nicht als boolesche Variable sondern einfach als normale Zahl gebraucht wird.

      Aber vielleicht irre ich mich ja auch. ;-)

      Gruß

      var

      1. Hallo,

        Aber vielleicht irre ich mich ja auch. ;-)

        Wenn ich dir sagte, dass ich Ferraris besitze und du mich dann fragtest "Wieviele denn?", antworte ich "Keine." Wäre das für dich logisch?

        Gruß
        Kalk

        1. Hallo,

          Hallo

          Wenn ich dir sagte, dass ich Ferraris besitze und du mich dann fragtest "Wieviele denn?", antworte ich "Keine." Wäre das für dich logisch?

          Das ist natürlich ein Punkt. - Touché!

          Wenn ich dir sagte, dass ich zwei Autos besitze die auf zwei Parkplätzen stehen, auf dem ersten Platz ein Ferrari und auf dem zweiten ein Trabant, und du mich dann fragtest, ob du dir den Wagen auf Parkplatz eins für's Wochenende ausleihen kannst und ich dir dann den Trabant vor die Tür stelle, wäre das für dich logisch?

          ;-)

          Gruß

          var

          1. Hallo,

            Wenn ich dir sagte, dass ich zwei Autos besitze die auf zwei Parkplätzen stehen, auf dem ersten Platz ein Ferrari und auf dem zweiten ein Trabant, und du mich dann fragtest, ob du dir den Wagen auf Parkplatz eins für's Wochenende ausleihen kannst und ich dir dann den Trabant vor die Tür stelle, wäre das für dich logisch?

            Da ich ja bereits 1 oder 2 mal was programmiert habe, hätte ich ja nicht nach dem Auto auf Platz eins gefragt, sondern nach dem auf dem ersten Platz :p

            Gruß
            Kalk

          2. Aloha ;)

            Wenn ich dir sagte, dass ich zwei Autos besitze die auf zwei Parkplätzen stehen, auf dem ersten Platz ein Ferrari und auf dem zweiten ein Trabant, und du mich dann fragtest, ob du dir den Wagen auf Parkplatz eins für's Wochenende ausleihen kannst und ich dir dann den Trabant vor die Tür stelle, wäre das für dich logisch?

            ;-)

            Absolut - um dieses altgediehnte Akronym mal wieder aufleben zu lassen - ROFL :D

            Grüße,

            RIDER

            --
            Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
            ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
      2. @@var:

        nuqneH

        Finde, dass 0 per default einfach 0 sein sollte

        Ist es.

        und wenn jemand zur Falsifizierung auf 0 oder 1 ( oder n > 0 ) zurückgreifen will, kann er oder sie das dann ja explizit bestimmen.

        Genau das hast du mit dem !-Operator doch getan.

        Jetzt verstehe ich dein Gejammer nicht.

        Qapla'

        --
        „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
        1. Hallo Gunnar

          Ja klar. Ausgehend von der Prämisse, dass 0 = _nichts_ und damit _false_ ist, ergibt !n bei n = 0 natürlich true.

          Wenn man aber davon ausgeht, dass 0 nicht _nichts_ ist, sondern einen Wert darstellt, nämlich 0, dann würde !n bei n = 0 false ergeben.

          Und das wäre _dann_ auch das gewünschte Ergebnis, wenn die Fragestellung nicht lautet:

          Ist der Wert true oder false? - Sondern wenn die Frage ist, ob überhaupt ein Wert angegeben wurde.

          ( 0 ) ist gleich (   ) nach Stand der Dinge, aber das kann einen Unterschied machen.

          Aber hey, ich bin nicht so ein Experte wie du, vielleicht mache ich das ja auch völlig falsch und es gibt eine andere Art zu überprüfen, ob bei einer Funktion eventuell kein Parameter eingegeben wurde, als zu schreiben...

          function myFunction ( param ) {  
            
            if ( !param ) { /* ... */ }  
            
          }
          

          ...was eben dann unerwünschterweise zu !param = true führt, wenn der eingegebene Wert für param = 0 ist, weil man diesen Wert zum Beispiel für die Positionsbestimmung in einem String oder Array benötigt.

          Gruß

          var

          1. Hallo,

            Ja klar. Ausgehend von der Prämisse, dass 0 = _nichts_ und damit _false_ ist, ergibt !n bei n = 0 natürlich true.

            das ist _eine_ Sichtweise.

            Man kann aber auch ähnlich wie in C an die Sache herangehen, dass jeder Wert, der numerisch 0 ist, auch als false gilt, und jeder Wert, der numerisch unglich 0 ist, als true. Und so wird es in Javascript im Prinzip auch gehandhabt, auch wenn durch die automatische Typumwandlung ein paar Stolpersteine im Weg liegen.

            Gerade deswegen funktionieren ja die "eleganten" Schreibweisen wie etwa diese:

            if (x%3) ...

            Nach deiner Argumentation ergäbe sich hier immer true, die Berechnung x%3 ergibt ja einen konkreten Wert, also nicht "nichts".
            Tatsächlich ergibt sich aber ein Wert ungleich 0, wenn x nicht durch 3 teilbar ist, dann gilt der Ausdruck als true und die Bedingung als erfüllt; und der Wert 0, wenn x durch 3 teilbar ist, dann gilt der Ausdruck als false und die Bedingung als nicht erfüllt.

            Wenn man aber davon ausgeht, dass 0 nicht _nichts_ ist, sondern einen Wert darstellt, nämlich 0, dann würde !n bei n = 0 false ergeben.
            Und das wäre _dann_ auch das gewünschte Ergebnis, wenn die Fragestellung nicht lautet:
            Ist der Wert true oder false? - Sondern wenn die Frage ist, ob überhaupt ein Wert angegeben wurde.

            Was du erwartest oder forderst, ist also eher ein Test auf Existenz, ähnlich dem Test mit isset() in PHP. Das hat Javascript aber in der Form AFAIK nicht.

            So long,
             Martin

            --
            Idealismus wächst mit der Entfernung zum Problem.
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
            1. Hallo,

              Hallo Martin

              Was du erwartest oder forderst, ist also eher ein Test auf Existenz, ähnlich dem Test mit isset() in PHP. Das hat Javascript aber in der Form AFAIK nicht.

              Erstmal danke für den Input! ;-)

              Den Test auf Existenz gibt es schon. Es kommt eben darauf an, _wie_ man vergleicht.

              Der !-Operator vergleicht eben nur true / false. Nur ! schließt also auch den Wert 0 mit ein, weshalb dieser Vergleich zu allgemein ist.

              Wenn ich die Existenz eines Wertes checken will, muss ich prüfen ( wert == null ) bzw. ( wert != null ).

              Wohingegen === null nur dann true bzw. !== null nur dann false ergeben würde, wenn der Wert tatsächlich _null_ ist.

              Es kommt also auf die Typgenauigkeit des Vergleichs an.

              Allerdings könnte man natürlich darüber nachdenken, für diesen Fall einfach !!wert zu schreiben. Nur so als Idee. ;-)

              Gruß

              var

              1. Ahoi

                Allerdings könnte man natürlich darüber nachdenken, für diesen Fall einfach !!wert zu schreiben. Nur so als Idee.

                Als schlechte Idee.

                Denn das gibt es schon und es meint einfach 'doppelte Verneinung'.

                Hmmh, dann vieleicht #wert? Wie wäre es damit? Glaube das gibt es noch nicht, oder? ;-)

                Gruß

                var

              2. Hi,

                Wenn ich die Existenz eines Wertes checken will, muss ich prüfen ( wert == null ) bzw. ( wert != null ).

                Wohingegen === null nur dann true bzw. !== null nur dann false ergeben würde, wenn der Wert tatsächlich _null_ ist.

                Eben.

                Deshalb lieber mit typeof param == "undefined" prüfen – wenn *kein* Parameter übergeben wurde, ergibt das true – in allen anderen Fällen¹ wie 0, 1, "", null, false, … ergibt es false.

                ¹ außer wenn explizit undefined übergeben wird.

                Es kommt also auf die Typgenauigkeit des Vergleichs an.

                Und darauf, dass man sich im Klaren darüber ist, was bzw. worauf man eigentlich vergleicht ;-)

                Allerdings könnte man natürlich darüber nachdenken, für diesen Fall einfach !!wert zu schreiben. Nur so als Idee. ;-)

                Betreib mal ein bischen Recherche, und du wirst feststellen, dass du darauf jetzt leider keinen Erfinderstolz geltend machen kannst … das wird bereits als eine Art Pattern verwendet.

                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. Hi,

                  Hi

                  Deshalb lieber mit typeof param == "undefined" prüfen – wenn *kein* Parameter übergeben wurde, ergibt das true – in allen anderen Fällen¹ wie 0, 1, "", null, false, … ergibt es false.

                  ¹ außer wenn explizit undefined übergeben wird.

                  Danke für den Hinweis!

                  Betreib mal ein bischen Recherche, und du wirst feststellen, dass du darauf jetzt leider keinen Erfinderstolz geltend machen kannst … das wird bereits als eine Art Pattern verwendet.

                  Ist mir 5 Minuten nach diesem Post schon aufgefallen. ;-)

                  Ist #param als Alternative eigentlich auch schon aus dem Rennen? ;-)

                  Nochmal Dank und Gruß

                  var

        2. Hallo Gunnar

          Spar dir die Antwort. Ich hab's jetzt verstanden.

          Mea maxima culpa.

          Gruß

          var

  2. hi var,

    Hallo miteinander!

    Ich bin gerade etwas verwirrt ob der Bedeutung der Zahl 0 in JavaScript: Bislang dachte ich immer, dass 0 in jedem Fall 0 ist, nicht aber null! ;-)

    Wenn ich jedoch in einer Funktion einen Parameter ( n ) habe und diese Funktion mit dem Wert 0 für diesen Parameter aufrufe, dann ergibt ( !n ) gleich true!

    Das sollte eigentlich nicht sein, oder? Ich meine, dafür gibt es ja das reservierte Wort null als speziellen Null-Wert. 0 sollte also 0 sein, aber nicht null!

    Irgendwie nicht wirklich logisch, oder? ;-)

    Crockford kann viel über Javascript berichten, es gibt auch gute Vorträge, bei yahoo-theater glaube ich. Auch über die Entwicklungsgeschichte. Die Sprache ist - wenn ich das recht zusammenfasse - binnen 2 Wochen mit Fehlern entwickelt worden und bedingt durch den Browser-War (MS vs. Mozilla) war es nicht möglich, einvernehmlich die Grundfehler zu beseitigen. Deshalb spricht Crockford auch von den "good parts".

    Wenn Du typengenau vergleichst, hast du überhaupt keine Problem 0 !== null und auch !== false.

    Von allem anderen (typenlose Vergleiche) rät Crockford ab. S. mal auch http://javascript.crockford.com/survey.html und Google dazu ...; wenns dich interessiert.

    Es ist einiges unlogisch. https://www.youtube.com/watch?v=v2ifWcnQs6M ist einer seiner Talks Vorträge ...;

    mfg

    tami

    1. hi var,

      hi tami

      Wenn Du typengenau vergleichst, hast du überhaupt keine Problem 0 !== null und auch !== false.

      Ja, das war mein Denkfehler.

      Danke. ;-)

      Gruß

      var

    2. Hakuna matata!

      Wenn Du typengenau vergleichst, hast du überhaupt keine Problem

      Doch, auch der typsichere Vergleich birgt noch seine Fallstricke:

      NaN === NaN; // false  
      -0 === +0; // true
      

      In EcmaScript 6 gibt es die Funktion Object.is(), die zwei Parameter auf Gleichheit überprüft und dabei auch diese exotischen Fälle nicht außenvor lässt. Das ist die Art von Vergleich, die wir uns alle herbeisehnen.

      --
      “All right, then, I'll go to hell.” – Huck Finn
      1. Hallo,

        Doch, auch der typsichere Vergleich birgt noch seine Fallstricke:

        NaN === NaN; // false

        Äpfel sind keine Birnen, aber beide sind NaN, möchtest du jetzt Äpfel === Birnen  auf true auswerten?

        -0 === +0; // true

          
        m.E. mathematisch völlig korrekt  
          
          
        Gruß  
        Kalk
        
        1. Hakuna matata!

          Doch, auch der typsichere Vergleich birgt noch seine Fallstricke:

          NaN === NaN; // false

          Äpfel sind keine Birnen, aber beide sind NaN, möchtest du jetzt Äpfel === Birnen  auf true auswerten?

          Nein, Äpfel und Birnen haben hoffentlich ihre Objekt-Identitäten, die man zum Vergleichen heranziehen kann. NaN ist ein primitiver Wert, hat keine Identität und ist trotzdem nicht strikt gleich (===) zu sich selbst. Diese Eigenschaften machen NaN einmalig in JavaScript, und Entwickler müssen entsrepchende Ausnahme- und Grenzfälle nur für NaN kennen. Man kann NaN zum Beispiel nicht einfach in einem Array finden:

          [NaN].indexOf( NaN ); // -1

          -0 === +0; // true[/code]

          m.E. mathematisch völlig korrekt

          Aus mathematischer Sicht ist es sicher sinnvoll, positive und negative Null gleich zu behandeln. Aus Perspektive eines JavaScript-Programmiers ist es komplizierter, denn der muss die Feinheiten von Maschinenzahlen und der Floating-Point-Arithmetik kennen. Und  in den Maschinenzahlen ist die positive Null eine andere Zahl als die negative Null.

          Es ist doch schön, dass es mit Object.is() endlich mal eine Vergleichsfunktion gibt, die so schön geradeaus und ohne Ausnahmen von der Regel arbeitet. Achja, und das beste ist natürlich, es ist eine _Funktion_ und kein Operator und man kann sie anderen Funktionen als Argument übergeben: Eine Identitätsfunktion – und alle funktionale-Programmierung-Liebhaber schreiben: "yay!"

          --
          “All right, then, I'll go to hell.” – Huck Finn
          1. @@1UnitedPower:

            nuqneH

            -0 === +0; // true

            m.E. mathematisch völlig korrekt

            Aus mathematischer Sicht ist es sicher sinnvoll, positive und negative Null gleich zu behandeln.

            Außer wenn es das nicht ist. Zwischen [latex]\lim_{x \to +0}\frac{1}{x}[/latex] und [latex]\lim_{x \to -0}\frac{1}{x}[/latex] liegen Unendlichkeiten.

            Auch ist 2015-01-28T09:06+00:00 etwas anderes als 2015-01-28T09:06-00:00. [RFC3339 §4.3, RFC2822 §3.3]

            Qapla'

            --
            „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)