2016-04-09 3 views
2

Есть ли способ создать общий цикл для цикла, который будет проходить через массив или объект правильно? Я знаю, что могу написать следующий цикл for, но он также будет прокручивать другие свойства, которые будут добавлены в массив.Javascript Generic For Loop

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

Под этим я имею в виду цикл, который будет итерацию:

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

х как

1 
2 

у как

first 
second 

Причиной этого является то, что я не будет знать до тех пор, пока не будет (x) Массив или объект). Является ли мой единственный способ создать функцию, которая будет проверяться во время выполнения?

+2

Если вы не знаете, какой тип вы имеете дело с, вы должны попытаться поставить себя в положение, когда вы знаете, тип того, что вы имеете дело с. Это самый простой способ предотвратить убийство со стороны коллеги. –

+0

Я определенно согласен с вашим комментарием. Ясность всегда желательна. Причина двусмысленности заключается в том, что я пишу компилятор для динамического языка, который компилируется в Javascript. Таким образом, я не обязательно знаю тип любого источника цикла, поэтому мне нужен общий способ создания цикла for, который будет работать во время выполнения. – cbillingham

+0

В JS все есть объект .. так что в вашем случае было бы разумнее рассматривать массивы и даже функции как объекты, потому что нет никакой реальной разницы. В вашем примере выше 'x = [1, 2]; Икс.foo = "foo"; 'Object.keys (x) перечислит вам' ["0", "1", "foo"] ', но его не покажет вам свойство' length', которое не перечислимо. В некоторых случаях вы можете использовать 'Object.getOwnPropertyNames (x);', и это вернет все собственные свойства, независимо от того, перечислены они или нет, как '[" 0 "," 1 "," length "," foo "]' – Redu

ответ

3

Используйте for..of loop.

Итерации по массивам

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

Перебор объектов

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

Во всяком случае, с точки кода зрения стиля, вы все равно должны проверить ваш объект, является ли массив, прежде чем перебирать над ним , Вы можете использовать Array.isArray для достижения этого. Таким образом, если предположить, data либо объект или массив:

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

Generic перекручивание

Поскольку в JavaScript, typeof [] === "object" (т.е. массивы являются объектами, которые используют индекс элемента в качестве ключа), вы можете уменьшить его одноконтурный с Object.entries:

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

Остерегайтесь, однако, что этот последний метод не будет делать справедливость вашего исключения динамических свойств (Е. г. array.foo), так как вы будете перебирать результат Object.entries. Если вам do необходимо сделать это исключение, используйте две петли for..of с Array.isArray, как показано выше.

0

Если это только значения индекса/ключа, которые вам нужны в соответствии с вашим ожидаемым выходом, вот простой однострочный.

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