Вопрос по циклу JS и массиву — почему так?
Потому что arr[j] сравнивается с arr[j+1]. Это два элемента подряд. Значит, j должен проходить не от 0 до максимума, а от 0 до максимума минус 1.
Если сделать условие j < i, то будет лишняя операция, которая не нужна, хоть и не мешает. Просто у нас от i до arr.length уже отсортированный массив. Поэтому a[j+1] будет равно a[i], но a[i] уже точно на своём месте и его никуда двигать не нужно. Поэтому это просто лишняя операция, для которой arr[j] > arr[j+1] будет заведомо ложно.
Внешний цикл начинается с индекса несуществующего элемента i = arr.length. Максимальный элемент массива это arr[ arr.length-1 ]. Внешний цикл надо начать с  i = arr.length-1. 
Тем не менее в коде всё равно присутствуют отсылки к несуществующим элементам массива в arr[ j+1 ], когда j = i-1, т.е. опять-таки запрашивается arr[ arr.length ]. Благо, что if возвращает false, когда arr[ j+1] оказывается undefined, и всё работает. Но это криво, неправильно, и вообще.