What array length is
Every array has a length property that holds the number of elements it contains. It is a property, not a method, so you write fruits.length with no parentheses. Writing fruits.length() is a type error, and at run time it fails because a number can't be called like a function.
const fruits: string[] = ["mango", "kiwi", "grapefruit"];
console.log(fruits.length); // 3
fruits.pop();
console.log(fruits.length); // 2
The length is not stored separately from the array: it follows the contents. After pop removes an element, or push adds one, length already shows the new count. An empty array [] has length 0.
Length and indices
Array indices start at 0, so an array of length n has valid indices from 0 to n - 1. The index length itself is one past the end. This gives two idioms for reaching items from the back of an array:
arr[arr.length - 1]is the last item.arr[arr.length - 2]is the second to last item.
const ages: number[] = [14, 32, 50, 21];
console.log(ages[ages.length - 1]); // 21
console.log(ages[ages.length - 2]); // 50
console.log(ages[ages.length]); // undefined
The last line shows the usual mistake. Reading an index that doesn't exist doesn't throw an error: it gives undefined. The compiler doesn't warn about it either, because it types ages[ages.length] as a plain number.
The lesson's exercise
The starting code declares two arrays, fruits with three strings and ages with four numbers. The exercise asks for three printed values:
- The number of fruits. Pass
fruits.lengthtoconsole.log. It prints3. - The last age. The array has four elements, so the last one sits at index
4 - 1. Writingages[ages.length - 1]reaches it without hard-coding the 3, and prints21. - The second to last age. Step one position further back with
ages[ages.length - 2]. It prints50.
const fruits: string[] = ["mango", "kiwi", "grapefruit"];
const ages: number[] = [14, 32, 50, 21];
console.log(fruits.length);
console.log(ages[ages.length - 1]);
console.log(ages[ages.length - 2]);
The expression ages.length - 1 is computed first, and the result is used as the index. If the array later gets a fifth element, the same line still finds the last one.
Where length shows up next
Most code that walks over an array depends on length. A counting loop runs while the index is less than the length, which makes the last pass use index length - 1 and stops before the invalid index:
const ages: number[] = [14, 32, 50, 21];
for (let i = 0; i < ages.length; i++) {
console.log(i, ages[i]);
}
It prints the four pairs 0 14, 1 32, 2 50 and 3 21. Using i <= ages.length instead would add a fifth pass with i equal to 4 and print undefined. Strings also have a length property: "kiwi".length is 4.
Length is also the way to test for an empty array. The condition arr.length === 0 is true only when there are no elements, and it is the safe check to make before reading arr[arr.length - 1].
Gotchas in TypeScript
- Empty arrays. For
[], the expressionarr[arr.length - 1]asks for index-1, which doesn't exist, so the result isundefined. Checkarr.length > 0first when the array might be empty. - Negative indices don't count from the end. In some languages
arr[-1]means the last item. In TypeScript it looks for a property named"-1"and finds nothing. The methodarr.at(-1)does return the last item, but this lesson uses thelength - 1form. - Length is not the highest index. An array with four items has length 4 and highest index 3.
- Length can be assigned. Setting
ages.length = 2cuts the array down to its first two elements, silently dropping the rest. It is rarely what you want, so avoid assigning to it by accident. - Types don't bound the index. The annotation
number[]says what the elements are, not how many there are. Nothing in the types stops an index from being too large, and the type annotations disappear when the code is compiled to JavaScript.
Key takeaways
arr.lengthis the element count, with no parentheses.- Valid indices run from
0toarr.length - 1. - The last item is
arr[arr.length - 1]and the second to last isarr[arr.length - 2]. - An index outside that range gives
undefined, not an error.