2016-04-09 16 views
2

Gibt es eine Möglichkeit, eine generische for-Schleife zu erstellen, die entweder ein Array oder ein Objekt korrekt durchläuft? Ich weiß, dass ich die folgende for-Schleife schreiben kann, aber es wird auch andere Eigenschaften durchlaufen, die zu einem Array hinzugefügt werden würden.Javascript Generisch For Loop

for (item in x) { 
    console.log(item) 
} 

Damit meine ich eine for-Schleife, die iteriert wird:

x = [1, 2] 
x.foo = "foo" 
y = {first:1, second: 2} 

x als

1 
2 

y als

first 
second 

Der Grund dafür ist, dass ich wird bis zur Laufzeit nicht wissen, welches x sein wird (entweder ein Array oder ein Objekt). Ist meine einzige Option, eine Funktion zu erstellen, die zur Laufzeit überprüft?

+2

Wenn Sie nicht wissen, welche Art Sie es zu tun, sollten Sie versuchen, sich in einer Position, wo Sie die Art von wissen, das, was Sie zu tun haben. Es ist der einfachste Weg, Totschlag von Kollegen zu verhindern. –

+0

Ich stimme definitiv mit Ihrem Kommentar überein. Klarheit ist immer zu wünschen. Der Grund für die Mehrdeutigkeit ist, dass ich einen Compiler für eine dynamische Sprache schreibe, die in Javascript kompiliert wird. Daher kenne ich nicht unbedingt den Typ der Quelle der Schleife, also brauchte ich eine generische Methode zum Erstellen einer for-Schleife, die zur Laufzeit funktionieren würde. – cbillingham

+0

In JS ist alles ein Objekt. In Ihrem Fall ist es vielleicht sinnvoller, Arrays zu behandeln und sogar als Objekte zu arbeiten, da es keinen wirklichen Unterschied gibt. In Ihrem Beispiel über 'x = [1, 2]; x.foo = "foo"; 'Object.keys (x) listet dir' ["0", "1", "foo"] 'auf, aber er zeigt dir nicht die Eigenschaft' length', die nicht aufzählbar ist. In einigen Fällen können Sie 'Object.getOwnPropertyNames (x);' verwenden und dies wird alle eigenen Eigenschaften zurückgeben, unabhängig davon, ob sie aufzählbar sind oder nicht wie '[" 0 "," 1 "," length "," foo "]' ' – Redu

Antwort

3

Verwenden Sie die for..of loop.

Iterieren über Arrays

const array = [1, 2]; 
array.foo = "test"; 
for (const number of array) { 
    console.log(number); // skips array.foo 
} 

Iterieren über Objekte

const object = { 
    some: "string", 
    number: 42 
}; 
for (const [key, value] of Object.entries(object)) { 
    console.log(key, value); 
} 

Wie auch immer, von einem Code-Stil Sicht, sollten Sie noch überprüfen, ob das Objekt ein Array ist, bevor Sie über sie iterieren . Sie können verwenden, um das zu erreichen. So ist data unter der Annahme, entweder ein Objekt oder ein Array:

if (Array.isArray(data)) { 
    for (const element of data) { 
     // Iterate over array 
    } 
} 
else { 
    for (const [key, value] of Object.entries(data)) { 
     // Iterate over object 
    } 
} 

Generisches Looping

Da in JavaScript, typeof [] === "object" (dh Arrays sind Objekte, die der Index des Elements als Schlüssel verwenden), man könnte es reduzieren eine einzelne Schleife mit Object.entries:

for (const [key, value] of Object.entries(data)) { 
    // For arrays, `key` will be the index 
} 

diese letztere Methode aber, dass Vorsicht nicht gerecht Ihren Ausschluß von dynamischen Eigenschaften tun (e. G. array.foo), da Sie das Ergebnis von Object.entries iterieren werden. Wenn Sie tun müssen diesen Ausschluss machen, verwenden Sie zwei for..of Schleifen mit Array.isArray wie oben gezeigt.

0

Wenn es nur die Index/Schlüsselwerte sind, die Sie für Ihre erwartete Ausgabe benötigen, hier ein einfacher Einzeiler.

function loop(x) { 
    return (Array.isArray(x) ? x : Object.keys(x)).forEach(el => console.log(el)); 
} 

loop(x); // 1 2 
loop(y); // First Second 

DEMO