Maurice: Problem mit Typenermittlung

Hallo Leute,

ich habe eine kleines Problem das mich jetzt schon einige Zeit gekostet hat.
In meinem Code wird fälschlicherweise die If Anweisung als true erkannt obwohl das Argument 5 in der Funktion leer (undefined) ist. Ich steige leider nicht dahinter wo der Fehler liegt...

  
  
if(arguments.length >= 5 || typeof arguments[5] != undefined) {  
  if(isNaN(arguments[5])) { var a = 6; } else { var a = 5; }  
  style[i]['end'] = arguments[a+i];  
  alert(arguments.length);  
  alert(arguments[5]);  
  } else {  
  style[i]['end'] = parseInt(CssData.style[i]['kind']);  
  if(typeof style[i]['end'] == undefined) { style[i]['end'] = 0; }  
}  
  

Beim Aufruf der Seite gibt es folgende Ausgabe:
Alert: 5
Alert: undefined

Normal zu erwartend wäre keine Alert Ausgabe ;)

Ich hoffe Ihr könnt helfen.
Vielen Dank!

  1. Hallo Maurice

    ich habe eine kleines Problem das mich jetzt schon einige Zeit gekostet hat.
    In meinem Code wird fälschlicherweise die If Anweisung als true erkannt obwohl das Argument 5 in der Funktion leer (undefined) ist. Ich steige leider nicht dahinter wo der Fehler liegt...

    if(arguments.length >= 5 || typeof arguments[5] != undefined) {
      if(isNaN(arguments[5])) { var a = 6; } else { var a = 5; }
      style[i]['end'] = arguments[a+i];
      alert(arguments.length);
      alert(arguments[5]);
      } else {
      style[i]['end'] = parseInt(CssData.style[i]['kind']);
      if(typeof style[i]['end'] == undefined) { style[i]['end'] = 0; }
    }

    
    >   
    > Beim Aufruf der Seite gibt es folgende Ausgabe:  
    > Alert: 5  
    > Alert: undefined  
    >   
    > Normal zu erwartend wäre keine Alert Ausgabe ;)  
      
    du hast den "Fehler" oder was auch immer durch deine alert-Anweisung doch schon selbst gefunden:  
    Wenn arguments.length größer oder gleich fünf ist. Dein alert(arguments.length) gibt aus, dass arguments.length gleich fünf ist.  
      
    Grüße.
    
    1. du hast den "Fehler" oder was auch immer durch deine alert-Anweisung doch schon selbst gefunden:
      Wenn arguments.length größer oder gleich fünf ist. Dein alert(arguments.length) gibt aus, dass arguments.length gleich fünf ist.

      Grüße.

      Vielen Dank für die schnelle Antwort.

      Wenn Argument 5 auch wirklich definiert wäre hätte ich das Problem nicht ;)
      Es sind im Funktionsaufruf nur 0 - 4 definiert und wie er auch selber anzeigt ist 5 "undefined".

      Sprich Argument 5 ist nicht angegeben und er weiß das er leer ist aber tut trotzdem so als wäre er da und ignoriert dann auch noch die if typeof Anweisung...

      1. Sprich Argument 5 ist nicht angegeben und er weiß das er leer ist aber tut trotzdem so als wäre er da und ignoriert dann auch noch die if typeof Anweisung...

        Hast du gesehen, dass du da ein ODER verwendest?

        1. Sprich Argument 5 ist nicht angegeben und er weiß das er leer ist aber tut trotzdem so als wäre er da und ignoriert dann auch noch die if typeof Anweisung...

          Hast du gesehen, dass du da ein ODER verwendest?

          Ja ist mir auch gerade gekommen :D Aber das Ergebniss ändert sich dennoch nicht...

          Da er fälschlicher weise das nicht existierende Argument 5 erkennt && Argument 5 auch nicht als undefined ansieht...

          Ich versteh das einfach nicht.

          1. Hey Maurice,

            Sprich Argument 5 ist nicht angegeben und er weiß das er leer ist aber tut trotzdem so als wäre er da und ignoriert dann auch noch die if typeof Anweisung...

            Hast du gesehen, dass du da ein ODER verwendest?

            Ja ist mir auch gerade gekommen :D Aber das Ergebniss ändert sich dennoch nicht...

            Da er fälschlicher weise das nicht existierende Argument 5 erkennt && Argument 5 auch nicht als undefined ansieht...

            Ich versteh das einfach nicht.

            ok, fangen wir mal von vorne an. Kannst Du kurz beschreiben, was Du vorhast? Und nochmal genau, welches if-statement Du meinst, welchen Wert die Variablen haben und was Du erwartest?

            Gruß, Dennis

            1. Hey Maurice,

              Sprich Argument 5 ist nicht angegeben und er weiß das er leer ist aber tut trotzdem so als wäre er da und ignoriert dann auch noch die if typeof Anweisung...

              Hast du gesehen, dass du da ein ODER verwendest?

              Ja ist mir auch gerade gekommen :D Aber das Ergebniss ändert sich dennoch nicht...

              Da er fälschlicher weise das nicht existierende Argument 5 erkennt && Argument 5 auch nicht als undefined ansieht...

              Ich versteh das einfach nicht.

              ok, fangen wir mal von vorne an. Kannst Du kurz beschreiben, was Du vorhast? Und nochmal genau, welches if-statement Du meinst, welchen Wert die Variablen haben und was Du erwartest?

              Gruß, Dennis

              Jawohl :D

                
                
              function funktion(var0, var1, var2, var3, var4) {  
                
              if(arguments.length >= 5 && typeof arguments[5] != undefined) {  
                
                 /* wird ausgeführt */  
                
                } else {  
                
                 /* sollte normal ausgeführt werden */  
                
                }  
                
              }  
                
              funktion(argument0, argument1, argument2, argument3, argument4);  
                
              
              

              Ich möchte einfach das wenn kein argument5 gesetzt wird dieses auch nicht in arguments.lenght gezählt wird.

              1. Hey Maurice,

                Ich möchte einfach das wenn kein argument5 gesetzt wird dieses auch nicht in arguments.lenght gezählt wird.

                soweit ich weiß sind in arguments alle übergebenen Werte, egal welchen Typs. Wenn Du die nicht mitzählen möchtest, fällt mir nichts besseres ein, als einfach mit einer Schleife über arguments zu laufen und dir selbst nen Zähler zu basteln.
                Und wenn es Dir nur um arguments[5] geht, könnte Dir eventuell schon if (arguments[5] != undefined) helfen.

                Gruß.

                1. Ergänzung: Hab Dein Beispiel mal getestet:

                    
                  function funktion(var0, var1, var2, var3, var4) {  
                    
                  	alert("Length: " + arguments.length);  
                  	alert("arguments[4]: " + typeof arguments[4]);  
                    
                  	if(arguments.length >= 5 && arguments[4] != undefined) {  
                    
                  		alert("arguments.length >= 5 && arguments[4] != undefined");  
                    
                  	} else {  
                    
                  		alert("else");  
                    
                  	}  
                    
                  }  
                    
                  alert("Test: type string");  
                  funktion("argument0", "argument1", "argument2", "argument3", "argument4");  
                    
                  alert("Test: type undefined");  
                  funktion("argument0", "argument1", "argument2", "argument3", undefined);  
                  
                  

                  Das sollte laufen. Mir ist aber noch was aufgefallen: Kann das sein, dass Du gar nicht arguments[5], sondern arguments[4] meinst? Weil Du ja nur 5 Parameter übergibst und JavaScript (wie viele andere Sprachen auch) mit 0 zu zählen beginnt, Deine Indexe also 0, 1, 2, 3 und 4 sind?

                  1. Ergänzung: Hab Dein Beispiel mal getestet:

                    function funktion(var0, var1, var2, var3, var4) {

                    alert("Length: " + arguments.length);
                    alert("arguments[4]: " + typeof arguments[4]);

                    if(arguments.length >= 5 && arguments[4] != undefined) {

                      alert("arguments.length >= 5 && arguments[4] != undefined");  
                    

                    } else {

                      alert("else");  
                    

                    }

                    }

                    alert("Test: type string");
                    funktion("argument0", "argument1", "argument2", "argument3", "argument4");

                    alert("Test: type undefined");
                    funktion("argument0", "argument1", "argument2", "argument3", undefined);

                    
                    >   
                    > Das sollte laufen. Mir ist aber noch was aufgefallen: Kann das sein, dass Du gar nicht arguments[5], sondern arguments[4] meinst? Weil Du ja nur 5 Parameter übergibst und JavaScript (wie viele andere Sprachen auch) mit 0 zu zählen beginnt, Deine Indexe also 0, 1, 2, 3 und 4 sind?  
                      
                    DAS ist natürlich völlig quatsch
                    
                    1. Hallo Gast,

                      DAS ist natürlich völlig quatsch

                      wäre schön gewesen, wenn Du das etwas spezifiziert hättest. SO ist Deine Aussage "natürlich völlig quatsch", weil damit keiner was anfangen kann, wenn er es mal im Archiv finden sollte.

                      Grundsätzlich gebe ich Dir aber recht, da ist ein bedeutender Fehler drin. Das kommt halt davon, wenn man zwischen Tür und Angel ohne nachzudenken einfach irgendwas per copy-paste übernimmt. Ich gelobe Besserung.

                      Eine gute Erklärung hat Mitleser ja schon gegeben. Darin hat Mitleser eigentlich auch schon den Fehler hier drin beschrieben.

                      Aber der Vollständigkeit halber: Hier

                        
                      if (arguments.length >= 5 && arguments[4] != undefined) {  
                          /* ... */  
                      }  
                      
                      

                      wird fälschlicherweise geprüft, ob die Variable arguments[4] und die Variable mit dem _Namen_ "undefined" einen ungleichen _Wert_ haben. Richtig wäre aber eine Überprüfung, ob die Variable arguments[4] von einem _Typ_ ungleich "undefined" ist, also z.B. so:

                        
                      if (arguments.length >= 5 && typeof arguments[4] !== "undefined") {  
                          /* ... */  
                      }  
                      
                      

                      Unabhängig davon ist aber, dass JavaScript bei einem Array mit dem Index 0 zu zählen beginnt.

                      So, genug geschrieben. Nächstes Mal wird's hoffentlich wieder besser mit meinen Antworten.

                      Gruß
                      und-für-den-T-Rex-noch-irgendein-quatsch-hinter-Gruß
                      Dennis

                      1. Hallo Gast,

                        DAS ist natürlich völlig quatsch

                        wäre schön gewesen, wenn Du das etwas spezifiziert hättest. SO ist Deine Aussage "natürlich völlig quatsch", weil damit keiner was anfangen kann, wenn er es mal im Archiv finden sollte.

                        Grundsätzlich gebe ich Dir aber recht, da ist ein bedeutender Fehler drin. Das kommt halt davon, wenn man zwischen Tür und Angel ohne nachzudenken einfach irgendwas per copy-paste übernimmt. Ich gelobe Besserung.

                        Eine gute Erklärung hat Mitleser ja schon gegeben. Darin hat Mitleser eigentlich auch schon den Fehler hier drin beschrieben.

                        Aber der Vollständigkeit halber: Hier

                        if (arguments.length >= 5 && arguments[4] != undefined) {
                            /* ... */
                        }

                        
                        >   
                        > wird fälschlicherweise geprüft, ob die Variable arguments[4] und die Variable mit dem \_Namen\_ "undefined" einen ungleichen \_Wert\_ haben. Richtig wäre aber eine Überprüfung, ob die Variable arguments[4] von einem \_Typ\_ ungleich "undefined" ist, also z.B. so:  
                        >   
                        > ~~~javascript
                          
                        
                        > if (arguments.length >= 5 && typeof arguments[4] !== "undefined") {  
                        >     /* ... */  
                        > }  
                        > 
                        
                        

                        Unabhängig davon ist aber, dass JavaScript bei einem Array mit dem Index 0 zu zählen beginnt.

                        So, genug geschrieben. Nächstes Mal wird's hoffentlich wieder besser mit meinen Antworten.

                        Gruß
                        und-für-den-T-Rex-noch-irgendein-quatsch-hinter-Gruß
                        Dennis

                        Soooo bevor hier streit ausbricht :D das Problem ist gelöst. (mehr oder weniger)
                        Also die Sache ist die. Ich will überprüfen ob ein 5. (>von 0 an gezählt<) oder mehr Argumente angehängt wurden da diese für zusätzliche Bearbeitungen nur hin und wieder benötigt werden. Deswegen habe ich sie flexibel gelassen.
                        Das 4. Argument ist ja beim Aufruf gegeben und muss deshalb ja nicht auf seine Existenz geprüft werden... ;)
                        Mit der Überprüfung von typeof arguments[5] != 'undefined' (mit Anführungsstrichen) wird es jetzt korrekt kontrolliert. Vielen Dank dafür.
                        Jedoch steht die Frage noch offen warum er bei 4 (>von 0 an gezählt<) angegebenen Argumenten bei der Abfrage arguments.length den Wert 5 auswirft obwohl nur 4 Argumente angegeben wurden...

                        1. Tach!

                          Bitte nur das zitieren, worauf du dich konkret beziehst, nicht immer das gesamte Vorposting.

                          Also die Sache ist die. Ich will überprüfen ob ein 5. (>von 0 an gezählt<) oder mehr Argumente angehängt wurden da diese für zusätzliche Bearbeitungen nur hin und wieder benötigt werden. Deswegen habe ich sie flexibel gelassen.
                          Das 4. Argument ist ja beim Aufruf gegeben und muss deshalb ja nicht auf seine Existenz geprüft werden... ;)

                          Ich würde die Parameter alle einzeln benennen, wenn sie nicht von ihrer Bedeutung her ein Array bilden. Ihre Existenz kann dann mit

                          /**  
                           * Beschreibung der Funktion  
                           * Programmdokumentation ist wichtig, am besten im [link:http://usejsdoc.org/index.html@title=JSDoc-Format]  
                           *  
                           * @param {string} foo Beschreibung von foo  
                           * @param {string} [bar] Beschreibung des optionalen Parameters bar  
                           */  
                          function foo(bar, qux) {  
                            if (qux != undefined)  
                              console.log('qux übergeben:', qux);  
                            else  
                              console.log('nur foo vorhanden, foo);  
                            
                          foo('baz');
                          

                          geprüft werden. Wenn null ein gültiger Inhalt ist, der von undefined unterschieden werden muss (oder wenn es nach Douglas Crockford geht), muss mit !== typsicher verglichen werden. null ist sonst gleich undefined, alle anderen Typen nicht.

                          Jedoch steht die Frage noch offen warum er bei 4 (>von 0 an gezählt<) angegebenen Argumenten bei der Abfrage arguments.length den Wert 5 auswirft obwohl nur 4 Argumente angegeben wurden...

                          Wenn du 1 Element an der Indexposition 0 hast, wieviele sind das dann? Nicht 0 sondern 1. length gibt die Anzahl an, nicht den Maximalwert. Wenn du 2 Elemente an den Positionen 0 und 1 hast, wieviele sind das dann? ... Wenn du 5 Elemente an den Positionen 0, 1, 2, 3 und 4 hast, wieviele sind das dann?

                          dedlfix.

                        2. Hey Maurice,

                          Jedoch steht die Frage noch offen warum er bei 4 (>von 0 an gezählt<) angegebenen Argumenten bei der Abfrage arguments.length den Wert 5 auswirft obwohl nur 4 Argumente angegeben wurden...

                          ergänzend zu dedlfix Beitrag, schau Dir mal folgendes Beispiel an:

                            
                          function test(param0, param1) {  
                              alert('Anzahl der übergebenen Argumente: ' + arguments.length);  
                              alert('Variable param0 hat den Wert ' + param0);  
                              alert('Variable param1 hat den Wert ' + param1);  
                            
                              for (i = 0; i < arguments.length; i++) {  
                                  alert('Argument mit Index ' + i + ' hat den Wert ' + arguments[i]);  
                              }  
                          }  
                            
                          test();  
                          test('arg1');  
                          test('arg1', 'arg2');  
                          test('arg1', 'arg2', 'arg3');  
                          
                          

                          Hilft Dir das weiter? Ansonsten kannst Du auch noch mal z.B. bei MDN reinschauen: Arguments object, arguments.length

                          Gruß, Dennis

                          1. Oh man okay! Ich frag mich warum bei Javascript jede Anweisung auf einer anderen Logik basiert... Deswegen nur das Nötigste in Javascript den Rest mach ich in PHP :D

                            Ihr habt mir auf jeden Fall sehr geholfen danke! :-)

                            1. Tach!

                              Oh man okay! Ich frag mich warum bei Javascript jede Anweisung auf einer anderen Logik basiert... Deswegen nur das Nötigste in Javascript den Rest mach ich in PHP :D

                              Auch PHP zählt bei Arrays von 0 an, und count() ergibt dabei 1. Diese Logik ist in ziemlich vielen Programmiersprachen anzutreffen.

                              dedlfix.

              2. function funktion(var0, var1, var2, var3, var4) {

                if(arguments.length >= 5 && typeof arguments[5] != undefined) {

                /* wird ausgeführt */

                } else {

                /* sollte normal ausgeführt werden */

                }

                }

                funktion(argument0, argument1, argument2, argument3, argument4);

                
                > Ich möchte einfach das wenn kein argument5 gesetzt wird dieses auch nicht in arguments.lenght gezählt wird.  
                  
                Verwirrend das ist :-)  
                  
                Was meinst Du mit "wenn kein argument5 gesetzt wird"? Zum einen ist die Formulierung schwamming, zum zweiten taucht "argument5" nirgends in den Parametern des Testaufrufs auf. Du machst Dir hier evtl. Dein Leben schwer, indem Du verschiedene Zählweisen miteinander mixt.  
                  
                Nehmen wir mal an, Du meintest eigentlich den 5.ten Paramter, also: "wenn kein argument4 gesetzt wird". In Deinem Beispiel prüfst Du aber den Typ von "arguments[5]". In den mir bekannten Programmiersprachen werden Arrays aber nullbasiert indiziert, sprich: Du prüfst auf ein 6.tes Argument, was Deine Funktion überhaupt nicht entgegennimmt.  
                  
                Also müsste er doch eigentlich in den else-Zweig springen? Leider nein, den typeof gibt Dir einen String "undefined" zurück, der ist aber "!=" der von Dir verwendeten Variablen(!) undefined (Anführungszeichen bewusst ausgelassen). Außer Du hättest irgendwo in Deinem Scope eine lokale Variable mit dem (String-)Wert "undefined" am Wickel.  
                  
                Das Thema gehört tatsächlich zu den weniger schönen Seiten an JavaScript. Man könnte da noch einiges anführen, aber geh für den Moment vielleicht einfach mal von der Rückgabe von typeof von einem String aus und mach aus der [5] eine [4].  
                  
                  
                
                
      2. Hallo Maurice

        Sprich Argument 5 ist nicht angegeben und er weiß das er leer ist aber tut trotzdem so als wäre er da und ignoriert dann auch noch die if typeof Anweisung...

        du hast die if-anweisung:

        if(arguments.length >= 5 || typeof arguments[5] != undefined) {

        wenn arguments.length >= 5 dann größer oder gleich fünf ist (laut deinem alert gleich 5) kommt er zu typeof also gar nicht.

        Grüße.

  2. Lieber Maurice,

    warum übergibst Du denn überhaupt so viele Argumente an eine Funktion? Wäre es nicht praktischer, wenn Du nur ein Argument, nämlich ein Objekt mit optionalen Eigenschaften übergäbest?

    function test (o) {  
      
        if (o.a && typeof o.a == "string") {  
            //  
        }  
      
        if (o.b && typeof o.b != NaN) {  
            //  
        }  
      
    }  
      
    test({  
        a: "Huhuu!",  
        c: 0.123  
    });
    

    Liebe Grüße,

    Felix Riesterer.

    --
    "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)