hawkmaster: for(i in array..) vs for(i = 0; ...) Erklärung gesucht ?

Hallo zusammen,

Ich habe heute gelesen das man ein Array auch mit der Schreibweise "in"
for(i in array..) durchlaufen kann.

Bei einem kleinen Beispiel unten gibt es bei der Schreibweise mit "In" zuerst die Ausgabe "super" dann "hallo" und dann etwas was ich mir garnicht erklären kann, nämlich:

function (value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === value) {
            return true;
        }
    }
    return false;
}

Bei der Schleife mit "for(i = 0; i < test_arr.length; i++)"
kommt nur wie erwartert "super" und dann "hallo"

  
var TestStr = 'super###hallo';  
test_arr = TestStr.split("###");  
for (i in test_arr) {  
  
}  
  
for(i = 0; i < test_arr.length; i++) {  
 alert(test_arr[i]);  
}  

vielen Dank und viele Grüße
hawk

  1. Lieber hawkmaster,

    mit der for-in-Schleife erreichst Du auch andere Eigenschaften eines Objektes, als die numerisch indizierten.

    function checkForIn () {  
        var myArray = ['eins', 'zwei'], i;  
        for (i = 0; i < myArray.length; i++) {  
            alert(i + ": " + myArray[i]); // kommt 2x: "0: eins" und "1: zwei"  
        }  
      
        for (i in myArray) {  
            alert(i + ": " + myArray[i]); // kommt öfters, z.B. "length: 2"  
        }  
    }
    

    Klarer geworden?

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hallo Felix,
      vielen Dank für deine Hilfe und Erklärung.

      Klarer geworden?

      ein wenig :-)
      Also bei der "In" Schreiweise werden zusätzlich auch noch die Eigenschaften des Objects ausgegeben?
      Warum aber diese Meldung mit "function"? woher kommt das?

      Wenn ich z.b. diese einfache Beispiel von
      http://www.w3schools.com/jS/tryit.asp?filename=tryjs_array_for_in
      ausprobiere.

        
      	var x;  
      	var mycars = new Array();  
      	mycars[0] = "Saab";  
      	mycars[1] = "Volvo";  
      	mycars[2] = "BMW";  
      	  
      	for (x in mycars)  
      	{  
      	document.write(mycars[x] + "<br />");  
      	}  
      
      

      kommt bei mir auch am Schluss zusätzlich noch "function (value) ... "

      vielen Dank und viele Grüße
      hawk

      1. var x;
        var mycars = new Array();
        mycars[0] = "Saab";
        mycars[1] = "Volvo";
        mycars[2] = "BMW";

        for (x in mycars)
        {
        document.write(mycars[x] + "<br />");
        }

        
        >   
        > kommt bei mir auch am Schluss zusätzlich noch "function (value) ... "  
          
        Dann hast du noch irgendetwas eingebunden. Bei mir kommen nur die 3 Werte.  
          
        Struppi.
        
        1. Lieber Struppi,

          Dann hast du noch irgendetwas eingebunden.

          z.B. Bibliotheken wie script.aculo.us undsoweiter...

          Bei mir kommen nur die 3 Werte.

          Bei mir auch (in IE, FF, Opera und Safari) und das stört mich sehr, denn das Array-Objekt enthält noch mehr Eigenschaften und Methoden als die numerischen. Warum werden die nicht auch mit ausgegeben?

          Beispiel-Script: http://www.felix-riesterer.de/self/for-schleifen.html

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. das Array-Objekt enthält noch mehr Eigenschaften und Methoden als die numerischen. Warum werden die nicht auch mit ausgegeben?

            Weil sie DontEnum (not enumerable - nicht iterierbar) sind.

            Mathias

        2. Hallo Struppi,

          danke auch dir und an die anderen Helfer.

          Dann hast du noch irgendetwas eingebunden. Bei mir kommen nur die 3 Werte.

          ja jetzt wird es mir verständlicher.
          Ich habe das

            
          	var x;  
          	var mycars = new Array();  
          	mycars[0] = "Saab";  
          	mycars[1] = "Volvo";  
          	mycars[2] = "BMW";  
          	  
          	for (x in mycars)  
          	{  
          	document.write(mycars[x] + "<br />");  
          	}  
            
          
          

          innerhalb einer Funktion eingebaut, die ich dann aufrufe.

          vielen Dank und viele Grüße
          hawk

          1. innerhalb einer Funktion eingebaut, die ich dann aufrufe.

            Selbst das erklärt nicht die Ausgabe, die du beschreibst.

            Struppi.

            1. Hallo Struppi,
              vielen Dank nochmal.

              Selbst das erklärt nicht die Ausgabe, die du beschreibst.

              hmm, ja du hast recht. Wenn ich das Script in einer völlig neuen Html Seite einbaue bekomme ich auch nur die drei Array Werte angezeigt.
              Nur bei meiner Ursprungsseite kommt noch die "function" Geschichte.

              Woher auch immer. Ich habe jetzt schon alles mögliche ausprobiert.
              Mich hätte es nur interessiert was dies verursacht.
              Aber mit der normalen "for" Schleife klappt es ja.

              viele Grüße
              hawk

              1. Woher auch immer. Ich habe jetzt schon alles mögliche ausprobiert.
                Mich hätte es nur interessiert was dies verursacht.

                Eine Erweiterung des Array Objektes.

                Struppi.

      2. Hi,

        Also bei der "In" Schreiweise werden zusätzlich auch noch die Eigenschaften des Objects ausgegeben?

        nein, nicht zusätzlich. Nur.

        Warum aber diese Meldung mit "function"? woher kommt das?

        Dein Objekt verfügt über eine Eigenschaft, die eine Funktion ist; siehe Struppis These.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
      3. kommt bei mir auch am Schluss zusätzlich noch "function (value) ... "

        Vermutlich wegen prototypischer Vererbung, d.h. Array.prototype, dem Prototyp für alle Array-Instanzen, wurde im Script eine Funktion hinzugefügt.

        Wenn man das macht, kann man (in ECMAScript Ed. 3) nicht angeben, dass die Eigenschaft nicht iterierbar sein soll. Sprich, die »vererbten« Eigenschaften bekommt man bei for-in immer mit hinein. Deshalb sollte man bei der Nutzung von for-in mit hasOwnProperty prüfen:

        for (var propName in obj) {  
           if (obj.hasOwnProperty(propName)) {  
              alert(propName + " ist nicht vererbt");  
           }  
        }
        

        Mathias

      4. Also bei der "In" Schreiweise werden zusätzlich auch noch die Eigenschaften des Objects ausgegeben?

        for-in und for sind i.d.R. nicht austauschbar und wenn du einen Array durchläufst, solltest du for verwenden, solange du nicht wirklich weißt, was du damit tust.

        for-in gibt dir alle iterierbaren Objekteigenschaften in ungeordneter Reihenfolge. Von denen will man beim Durchlaufen eines Arrays üblicherweise nur ausgewählte!

        for ist erst einmal eine Zählschleife, damit zählt man eine Variable hoch und greift anhand dieser Zahl auf Array-Element zu. Array-Elemente sind auch nur Objekteigenschaften, nur halt limitiert mit den numerischen Namen "0", "1", "2" usw.

        Wenn du die Elemente eines Arrays durchlaufen willst, bist du daher mit einer for-Schleife, die auf die Elemente über arr[X] zugreift, schon sehr gut bedient. Bei for-in müsstest du wie gesagt noch einige Prüfungen einbauen - aber wozu dieser Aufwand.

        Mathias

        1. @@molily:

          nuqneH

          for ist erst einmal eine Zählschleife

          Erst einmal nicht.

          for (expression1; expression2; expression3) statement

          ist eine andere Schreibweise für

          expression1;  
          while (expression2)  
          {  
            statement;  
            expression3;  
          }
          

          Freilich wird 'for' am häufigsten als Zählschleife eingesetzt.

          Qapla'

          --
          Bildung lässt sich nicht downloaden. (Günther Jauch)
          1. Hi Gunnar,

            for (expression1; expression2; expression3) statement

            ist eine andere Schreibweise für

            expression1;

            while (expression2)
            {
              statement;
              expression3;
            }

              
            das stimmt so nicht. Der konzeptionelle Unterschied kommt dann zum Tragen, wenn das Statement continue; ist bzw. enthaelt.  
              
              
            Viele Gruesse,  
            der Bademeister
            
          2. for ist erst einmal eine Zählschleife

            Erst einmal nicht.

            Würdest du bitte meine Sätze nicht aus dem Kontext reißen? Ich hatte nie vor, eine Aussage über for-Schleifen »an sich« zu machen. Ich denke, es war unmissverständlich klar, dass ich über das Durchlaufen von Arrays gesprochen habe und for (sowie for-in) auch nur unter diesem Aspekt betrachtet habe.

            Mathias

  2. Hallo zusammen,
    Erst nochmals herzlichen Dank an alle für die Hilfe und Erklärungsversuche.

    Nach langen suchen und forschen habe ich nun die Ursache für das Verhalten gefunden. Ich hatte irgendwann mal in meine ".js" Datei in der ich alle Funktionen habe folgenden Code eingefügt.
    Ich glaube es war ein Test weil ich nicht wusste (weiss) was es mit dem "prototype" aufsich hat.

      
    Array.prototype.contains = function(value) {  
        for (var i = 0; i < this.length; i++) {  
            if (this[i] === value) return true;  
        }  
        return false;  
    };  
    
    

    Tja, kaum ist das raus, klappt alles wunderbar.
    Ja so kann man sich ein ei legen.
    Aber immerhin habe ich jetzt wieder was dazugelernt und das "For in" kennengelernt.

    vielen Dank und viele Grüße
    hawk

    1. Ich glaube es war ein Test weil ich nicht wusste (weiss) was es mit dem "prototype" aufsich hat.

      Das ist das was ich mit Erweiterung des array Objektes gemeint habe.

      Array.prototype.contains = function(value) {
          for (var i = 0; i < this.length; i++) {
              if (this[i] === value) return true;
          }
          return false;
      };

        
      Damit kannst du prüfen ob ein Wert in dem Array vorkommt.  
      ~~~javascript
      var mycars = new Array();  
      mycars[0] = "Saab";  
      mycars[1] = "Volvo";  
      mycars[2] = "BMW";  
        
      alert(mycars.constains('Volvo'));  
      
      

      Struppi.