JavaScript Arrays

In programming, we often need to store lists of data—a shopping list, a queue of user IDs, or a collection of test scores. Instead of creating a separate variable for each item (item1, item2, item3), we use an Array.

An Array is a single variable that can hold multiple values. It is an ordered list, meaning the position of each item matters.

There are two ways to create an array, but one is significantly preferred.

The Array Literal (Standard)

The “literal” syntax uses square brackets []. This is the cleanest and most common way to define an array.

// An array of strings
const vegetables = ["Kale", "Bell Pepper", "Broccoli"];
console.log(vegetables);
// Output: (3) ['Kale', 'Bell Pepper', 'Broccoli']

// An array of mixed data types
// This includes an Object which is covered in a future lesson.
const mixedData = ["Text", 42, true, { name: "Object" }, null];
console.log(mixedData);
// Output: (5) ['Text', 42, true, {…}, null]

// An empty array
const emptyArr = [];
console.log(emptyArr);
// Output: []
JavaScript

The Array Constructor (AVOID)

You can also use the new keyword, but this is generally discouraged because it can be confusing.

// Creates an array with 3 empty slots (NOT [3])
const confusing = new Array(3); 
console.log(confusing); // Output: [empty × 3]

const lessConfusing = new Array(1, "two", true, {key: "value"});
console.log(lessConfusing);
// Result: [1, 'two', true, {key: 'value'}]
JavaScript

JavaScript arrays are Zero-Indexed. This means the count starts at 0, not 1.

  • The First element is at index 0.
  • The Second element is at index 1.
const colors = ["Red", "Green", "Blue"];

// Accessing elements
console.log(colors[0]); // Output: Red
console.log(colors[1]); // Output: Green
console.log(colors[2]); // Output: Blue

// Accessing an index that doesn't exist returns 'undefined'
console.log(colors[5]); // Output: undefined
JavaScript

Accessing the Last Array Element

Since the index starts at 0, the last item is always at the position length - 1.

const animals = ["Deer", "Owl", "Fox"];

// Old School Way
console.log(animals[animals.length - 1]); // Output: Fox

// Modern Way (ES2022) - .at() supports negative indexing
console.log(animals.at(-2)); // Output: Owl (2nd to last element)
JavaScript

Arrays are Mutable, meaning you can change their contents even if the array itself is declared with const. The const keyword prevents you from reassigning the variable name to a new array, but it does not protect the data inside the array.

Note: creating a new array (e.g., using .slice() or the spread syntax – both seen below) instead of modifying the original is important because JavaScript arrays are mutable objects, meaning changes made to a referenced array in one part of your code would unexpectedly affect other parts that still rely on the original data structure.

// Immutability Reminder with Strings
let name = "Bob";
let name2 = name; // name2 creates a separate copy of the value
name = name.toUpperCase(); // Creates a *new* string "BOB" and assigns it to name
console.log(name); // Output: "BOB"
console.log(name2); // Output: "Bob" (original value remains unchanged)

// Array Mutability - Names Example
const namesArray = ["Bob", "Rodney", "Cindy"];
namesArray[1] = "Bill" // Changing index 1 in the array.
console.log(namesArray); // Output: ['Bob', 'Bill', 'Cindy']

// Array Mutability - Numbers Example
const numbersArray = [10, 20, 30];
const numbers2 = numbersArray.pop(); // Removes last array index.
console.log(numbersArray); // Output: [10, 20]
JavaScript

The Length Property

The .length property returns the total count of items. Interestingly, it is also writable.

// Getting the length of an array:
const checkArray = [10, true, "word", null, undefined]
console.log(checkArray.length); // Output: 5
// Checking the index (0) of the array:
console.log(checkArray[0]); // Output: 10


// Modifying a sentence with array index length.
const animals = ['Deer', 'Rabbit', 'Fox', 'Cat'];
let sentence = `The animals are `;
// Loop through each animal by its index (0, 1, 2, 3)
for (let i = 0; i < animals.length; i++) {
   // Check if we have reached the final item in the array
   if (i === animals.length - 1) {
      sentence += `and ${animals[i]}.`; // Add "and" and a period for the last item
   } else {
      sentence += `${animals[i]}, `;     // Add a comma for all previous items
   }
}
console.log(sentence); 
// Output: The animals are Deer, Rabbit, Fox, and Cat.
JavaScript

Destructuring is a modern syntax that allows you to “unpack” values from an array into distinct variables. It is essentially a shortcut for manual assignment.

const coordinates = [100, 200, 300];

// The Old Way
// const x = coordinates[0];
// const y = coordinates[1];

// The Destructuring Way
const [x, y] = coordinates;

console.log(x); // 100
console.log(y); // 200
// Note: 300 is ignored because we didn't provide a variable for it.
JavaScript

Destructuring: Skipping Elements/Indexes

You can skip indices by leaving a “hole” (a comma) in the destructuring pattern.

const names = ["Ricky", "Jen", "Bob"];

// Skip "Jen" with comma
const [first, , third] = names;

console.log(first); // Output: Ricky
console.log(third); // Output: Bob
JavaScript

Destructuring: Setting Default Values

You can set a fallback value if the index you are trying to extract is undefined (missing) when destructuring.

const namesTwo = ["Ricky", "Bob"];

// There is no third or fouth index
const [firstIndex, , thirdIndex, fourthIndex] = namesTwo;

console.log(firstIndex); // Output: Ricky
console.log(thirdIndex); // Output: undefined
console.log(fourthIndex); // Output: undefined

// Setting Defaults for third and fourth indexes:
const fourthDefault = "Barb";
const [
	firstIndex2,
	secondIndex2,
	thirdIndex2 = "Jen",
	fourthIndex2 = fourthDefault
] = namesTwo;

console.log(firstIndex2); // Output: Ricky
console.log(secondIndex2); // Output: Bob
console.log(thirdIndex2); // Output: Jen
console.log(fourthIndex2); // Output: Barb
JavaScript

The slice() method is used to create a new array containing a shallow copy of a portion of an existing array without modifying the original. 

const originalArr = [1, 2, 3, 4, 5];
// With no arguments, .slice() copies the entire array:
const copyArr = originalArr.slice();
console.log(copyArr); // Output: [1, 2, 3, 4, 5]

// Extract Arrays from the index:
// "0" index would be the same as an empty .slice()
const copyArr2 = originalArr.slice(2)
console.log(copyArr2); // Output: [3, 4, 5]

// Extract Arrays from last index with negative:
const copyArr3 = originalArr.slice(-2)
console.log(copyArr3); // Output: [4, 5]

// Extract a Range of Array indexes:
const copyArr4 = originalArr.slice(1, 3)
console.log(copyArr4); // Output: [2, 3]

const copyArr5 = originalArr.slice(2, -2)
console.log(copyArr5); // Output: [3]
JavaScript

The Spread operator (...) allows you to “expand” an array into its individual elements. It is commonly used for Copying and Merging arrays.

Note: the JavaScript spread operator () is used with data types other than arrays. It can be used with any iterable object, such as strings, maps, and sets, as well as with objects. The spread operator will be revisited in the last lesson of this section.

// Copying an Array with ...spread:
const original = [1, 2, 3];
const copy = [...original]; // Creates a brand new clone
console.log(copy); // Output: [1, 2, 3]

// Merging Arrays with ...spread:
const groupA = ["User1", "User2"];
const groupB = ["User3"];
const allUsers = [...groupA, ...groupB];
console.log(allUsers); // ["User1", "User2", "User3"]

// Adding Array Elements with ...spread:
const myArray1 = [1, 2, 3]
const myArray2 = [6, 7]
const myArray3 = [9, 10]
const allNumbers = [
	0, ...myArray1, "four", "five",
	...myArray2, "eight", ...myArray3
]
console.log(allNumbers);
// Output: [0, 1, 2, 3, 'four', 'five', 6, 7, 'eight', 9, 10]
JavaScript

The array rest operator (...) in JavaScript is used in destructuring assignments to collect all remaining elements into a new array. 

Note: the rest operator (…) must always be at the end of an array destructuring assignment (or the end of parameters in a JavaScript function declaration).

const scores = [1, 2, 3, 4, 5];
const [first, second, ...others] = scores;
console.log(first); // Output: 1
console.log(second); // Output: 2
console.log(others); // Output: [3, 4, 5]
JavaScript

Arrays can hold any data type, including other arrays. When an array is inside another array, it is called a Nested or Multi-Dimensional Array.

This is commonly used for:

  • Grids/Matrices: (Spreadsheets, Chess boards, Pixel maps).
  • Coordinate Systems: [[x,y], [x,y]].
  • Data Grouping: Grouping user data without using objects.

Basic Nested Array Syntax:

You access nested items by chaining square brackets. The first bracket selects the row (the inner array), and the second bracket selects the item inside that row.

const nestedArr = [
	[1, 2, 3], // Row 0
	[4, 5, 6], // Row 1
	[7, 8, 9]  // Row 2
];

// Access the Row
const row1 = nestedArr[0]; 
console.log(row1); // Output: [1, 2, 3]
console.log(nestedArr[1]); // Output: [4, 5, 6]

// Access the Item
// Syntax: array[rowIndex][itemIndex]
console.log(nestedArr[0][2]); // Output: 3
console.log(nestedArr[2][1]); // Output: 8
JavaScript

Real World Use Case: Data Tables:

Developers often encounter this structure when parsing CSV files (Comma Separated Values) or data grids.

const sheetData = [
	["Name", "Role", "Salary"], // Row 0 (Headers)
	["Jan", "Dev", 90000], // Row 1
	["Bob", "Manager", 100000] // Row 2
];
const bobName = `${sheetData[0][0]}: ${sheetData[2][0]}`
console.log(bobName); // Output: Name: Bob
JavaScript

Nested Destructuring:

You can even destructure nested arrays. This is useful for coordinate data.

const route = [
	[1, 2], // Start Point [x, y]
	[3, 4]  // End Point [x, y]
];
// Unpacking nested array values:
const [[startX, startY], [endX, endY]] = route;

console.log(startX); // Output: 1
console.log(startY); // Output: 2
console.log(endX); // Output: 3
console.log(endY); // Output: 4
JavaScript

Mixed Nested Array Data Types:

Though we haven’t covered Objects or Functions yet in this series, these examples will show how to access them in nested arrays.

const mixedData = [["Red", "Green", {name: "Bob"}], "Blue"];
// Access the Object in the nested Array & Uppercase:
console.log(mixedData[0][2].name.toUpperCase()); // Output: BOB


// Array with a standard and arrow function as elements:
const moreData = [
  function() { return "Hello!"; },
  [
	{ objName: (name) => `Hello, ${name}!`}
  ]
];
// Access index 0 function and run it:
console.log(moreData[0]()); // Output: Hello!
// Access index 1, item 1, object arrow function and pass an argument:
console.log(moreData[1][0].objName("Jan")); // Output: Hello, Jan!
JavaScript

We’ll cover objects later in this section. Since both arrays and objects can hold data, which should we use?

  • Use Arrays when order is important (e.g., a timeline of events, a leaderboard).
  • Use Objects when you need labeled data elements (e.g., a user profile with name and email).

Technical Check:

In JavaScript, Arrays are technically a special type of Object. This can lead to confusion when checking types. In an earlier lesson we used the typeof operator to check the data type, but with arrays it shows object. The correct way to check for an array is by using the Array.isArray() method.

const myList = [1, 2, 3];
console.log(typeof myList); // Output: object
console.log(Array.isArray(myList)); // Output: true

console.log(Array.isArray([])); // Output: true
JavaScript
ConceptSyntax ExampleDescription
Creationconst arr = []Creating an empty list.
Accessarr[0]Getting the first value.
Nested Accessarr[0][1]Accessing items inside nested arrays (Grids).
Last Itemarr.at(-1)Getting the last value (Modern).
Lengtharr.lengthThe count of items.
Destructuringconst [a, b] = arrUnpacking values into variables.
Spreadconst newArr = […arr]Cloning or expanding an array into individual elements.
Rest Patternconst [a, …rest] = arrCollecting the remaining items into a new array.
Type CheckArray.isArray(arr)Returns true if it is an array.

Arrays are arguably the most fundamental data structure in software engineering, serving as the backbone for everything from rendering lists of products on a website to processing complex datasets in backend algorithms. Mastering array manipulation is not just a syntax requirement; it is a critical skill for managing and transporting data efficiently in any application.