Оператор запятая в цикле for со множественным условием

В Си-подобных языках есть разделитель-запятая как часть синтаксиса, а есть оператор-запятая как малоизвестный, но всё же полноценный бинарный оператор. В цикле for со множеством параметров есть и то и другое, что может ввести в заблуждение.

Показывать буду на примере JavaScript (ECMAScript) ибо так проще всего, но в остальных Си-подобных языках (C++, C#, Java, PHP) всё точно также. Можете попробовать повыполнять эти примеры кода прямо у себя в браузере. В Chromium надо лишь открыть новое пустое окно введя в URL строку about:blank, и открыть консоль разработчика клавишей F12, а дальше на вкладку Console и вперёд вводить код.
Есть цикл:

for (i = 0, j = 0; i < 1, j < 2; i++, j++) {console.log(i, j);}

Два объявления и задания счётчика, два условия, два инкремента для этих счётчиков.
Результат:

0 0
1 1

Цикл работал до тех пор пока второе условие не стало false. Первое условие стало false ещё на первой итерации, но цикл проигнорировал false первого условия. Из-за такого поведения я сперва думал, что цикл будет продолжаться пока хоть одно из перечисленных условий возвращает true так как в нескольких условиях цикла for запятая между ними видимо интерпретируется как логическое «или» ||, i.e. всё условие цикла будет считаться верным если хотя бы одна из его частей вернёт true. Значит, если такого поведения не требуется, а нужно чтобы все части условия возвращали true, i.e. цикл прекращался если не выполняется хотя бы одно из заданных условий, как и задумывается по прямой логике, то между всеми условиями надо явно использовать логическое «и» &&:

for (i = 0, j = 0; i < 1 && j < 2; i++, j++) {console.log(i, j);}

Результат:

0 0

А что если так:

for (i = 0, j = 0; i < 2, j < 1; i++, j++) {console.log(i, j);}

Результат:

0 0

Не может быть! В чём же дело? Выходит, что цикл смотрит только на второе условие, а первое игнорирует. Да! Всё дело оказалось в том, что условие в цикле for всегда будет одно, а запятая между этими условиями рассматривается интерпретатором (или компилятором) не в качестве разделителя-запятой как часть синтаксиса, а в роли оператора-запятой как оператор, а не синтаксис цикла. Короче говоря, запятая в условии цикла for это всегда оператор-запятая, а не разделитель-запятая.

Бинарный оператор-запятая имеет низкий приоритет и всегда возвращает правый операнд. Вот и получалось, что цикл как бы смотрит только на второе условие, а первое игнорирует.

В общем, знайте, что в цикле for всегда может быть только одно условие, а при попытке задать их несколько запятая будет считаться оператором, а не разделителем.