Почему свойство length начинает считать с единицы, а не с нуля, если в массиве счет начинается с нуля?
Как раз с длиной всё очевидно. length – количество элементов массива:[]; // сколько элементов? – 0
['a']; // сколько элементов: 1
['a', 'b', 'c']  // 3
Индексы начинают с нуля, потому, что индекс – это смещение.
Исторически, с низкоуровневых языков программирования.
В памяти под массив выделена некоторая память, начиная с адреса X.
Последовательно находятся ячейки одинаковой длины. Чтобы найти, где лежит значение i-го элемента, к адресу X прибавляют i * size байт. Самый первый элемент начинается сразу с адреса X. Его индекс 0.

Так же и со строкой в JavaScript: к буквам можно обращаться по индексу, как к элементам массива.
"abcd"[1] // "b"
"abcd"[3] // "d"Представьте, что в начале строки стоит курсор. Курсор возвращает букву перед которой стоит. Индекс – на сколько вправо надо этот курсор подвинуть.

Эта особенность index / length общепринята во многих языках программирования. Так же, как для интервалов часто принято включать начало и исключать конец: [a; b) – например, в методе массива slice(), который вырезает кусок массива, если указать  slice(1, 5) — вытащит элементы с индексами 1, 2, 3, 4 – включая 1-й, но не доходя до 5.
Все правильно, элементов в массиве 3, как вы и указали, но, в JavaScript, счет начитается с 0 а не с 1. Как-то так.