
JavaScript
Зачем в JS "foreach" назвали "for of", не так как везде ?

foreach - далеко не общепринятый стандарт. Например, в C++, Java это тоже for специального вида, но вместо of используется двоеточие.
В JS сначала были обычный for и for-in, итерирующий по значениям ключей объекта (включая индексы массива). А for-of, итерирующий по значениям ячеек массива, добавили относительно недавно - т. к. for-in во многих случаях был неудобен.
А слово forEach в JS используют для перебирающего метода массива:
https://learn.javascript.ru/array-methods#perebor-foreach
В JS сначала были обычный for и for-in, итерирующий по значениям ключей объекта (включая индексы массива). А for-of, итерирующий по значениям ячеек массива, добавили относительно недавно - т. к. for-in во многих случаях был неудобен.
А слово forEach в JS используют для перебирающего метода массива:
https://learn.javascript.ru/array-methods#perebor-foreach
В JS есть и foreach и for of
Иван Ильин
Врешь, нет foreach, есть Array.forEach(), что извращение.
У меня для тебя плохие новости: в JS очень многое не так, как везде. И пригоршня костылей для совместимости с багами первых реализаций JS, не поддающаяся логике.
Потому что там еще есть for in.
А for in там нужен, например, для того, чтобы можно было пройти по полям объекта, а не только их значениям.
Например
const obj = { x: 1, y: 2 };
for (const key in obj) {
console.log(key);
}
Вывод:
x
y
В статически типизированных языках такого нет, потому что любой объект имеет какой-то тип и программист может просто проверить тип объекта, в то же время именно поля получить может быть вообще невозможно, если язык не поддерживает рефлексию из коробки.
Пример - C++. Сохраняет ли он в бинарник поля, как и названия методов\классов - зависит от компилятора, это не стандарт.
А for in там нужен, например, для того, чтобы можно было пройти по полям объекта, а не только их значениям.
Например
const obj = { x: 1, y: 2 };
for (const key in obj) {
console.log(key);
}
Вывод:
x
y
В статически типизированных языках такого нет, потому что любой объект имеет какой-то тип и программист может просто проверить тип объекта, в то же время именно поля получить может быть вообще невозможно, если язык не поддерживает рефлексию из коробки.
Пример - C++. Сохраняет ли он в бинарник поля, как и названия методов\классов - зависит от компилятора, это не стандарт.
"forEach" и "for of" имеют очень немного общего и кажутся равнозначными только по причине реализации "for of" для всех массивоподобных объектов.
"forEach" является методом массивоподобных объектов, для обхода всех элементов.
"for of" является оператором вызова метода итератора, и это необязательно массивоподобные объекты.
В JS итератор может быть реализован одним из вариантов:
* протокол итератора + символы Symbol.iterator или Symbol.asyncIterator
* функции-генератора function*(){}
Ниже, оператор "for of" вызывает .next() до тех пор,
пока он не возвратит {done:true}, и это совсем не массив:
const notArray = {
async *[Symbol.asyncIterator]() {
const end = Date.now() + 1000
while (Date.now() < end) {
yield String.fromCharCode(Math.floor(Math.random() * (90 - 65)) + 65)
await new Promise((s) => setTimeout(s, 100))
}
}
}
void (async () => {
for await (let item of notArray) {
console.log(await item)
}
})()
https://jsfiddle.net/po5swL1m/
"forEach" является методом массивоподобных объектов, для обхода всех элементов.
"for of" является оператором вызова метода итератора, и это необязательно массивоподобные объекты.
В JS итератор может быть реализован одним из вариантов:
* протокол итератора + символы Symbol.iterator или Symbol.asyncIterator
* функции-генератора function*(){}
Ниже, оператор "for of" вызывает .next() до тех пор,
пока он не возвратит {done:true}, и это совсем не массив:
const notArray = {
async *[Symbol.asyncIterator]() {
const end = Date.now() + 1000
while (Date.now() < end) {
yield String.fromCharCode(Math.floor(Math.random() * (90 - 65)) + 65)
await new Promise((s) => setTimeout(s, 100))
}
}
}
void (async () => {
for await (let item of notArray) {
console.log(await item)
}
})()
https://jsfiddle.net/po5swL1m/
Афанасьев Сергей
А таким нехитрым способом, можно посмотреть что реально происходит внутри "for of" при обращении к массивам:
const arr = [1,2][Symbol.iterator]()
console.log(arr.next());
console.log(arr.next());
console.log(arr.next());
const arr = [1,2][Symbol.iterator]()
console.log(arr.next());
console.log(arr.next());
console.log(arr.next());
Похожие вопросы
- Для чего нужен цикл for...of, если есть цикл for...in
- Помогите с js плз. с forEach
- Помогите определиться с выбором нового языка (JS(TS) vs Java)
- Js фреймворки, что полезного можно для себя найти?
- В чем цель фреймворков js web?
- [HTML/CSS/JS] Как сохранять изменённые в .js данные оффлайн-сервера локально?
- Почему jQuery методы популярнее js методов при общении с ДоМ?
- ПОЧЕМУ JS ТАКОЙ НЕПОНЯТНЫЙ???
- есть ли JS что-то типо for(i in array, array[i] == 1) сделать то-то else сделать другое
- вопрос по JS. " простой ()";
Это оператор вызова (и одновременной проверки) метода next() итератора.
Итератор, в свою очередь, может просто генерить данные, и быть совсем не массивом.