# JavaScript Arrays 101

## 1\. What Are Arrays and Why Do You Need Them?

Imagine you want to store the marks of 5 students.

Without arrays, you'd do this:

```javascript
const marks1 = 85;
const marks2 = 90;
const marks3 = 78;
const marks4 = 92;
const marks5 = 88;
```

Fine for 5 students. What about 50? What about 500? You'd have 500 variables with no connection to each other. Printing them all means writing 500 `console.log` lines. Changing something means hunting through 500 variables. It's unmanageable.

Arrays fix this:

````javascript
const marks = [85, 90, 78, 92, 88];
```

One variable. All 5 values. In order. And if you have 500 students tomorrow, the array handles it the same way — you just add more values.

**Think of an array like a row of boxes.** Each box holds one value. Each box has a number on it starting from 0. You can open any box by its number whenever you want.
```
 ┌─────┬─────┬─────┬─────┬─────┐
 │ 85 │ 90|    78  │  92 │88 │
 └─────┴─────┴─────┴─────┴─────┘
    0     1     2     3     4      ← index numbers
````

That's an array. Nothing more complicated than that.

### Storing Values Individually vs Using an Array

Here's the same data, both ways:

```javascript
// Individual variables — don't do this for lists
const fruit1 = "apple";
const fruit2 = "banana";
const fruit3 = "mango";
const fruit4 = "grapes";
const fruit5 = "orange";

// Array — do this instead
const fruits = ["apple", "banana", "mango", "grapes", "orange"];
```

With individual variables, adding a 6th fruit means creating a new variable. Looping through them all is impossible without writing each one manually. Passing them to a function means 5 separate arguments.

With an array, you add one more value inside the brackets. Looping is one line of code. Passing everything to a function is one argument. The array scales. Individual variables don't.

### 🔥 Gotcha #1 — Arrays in JavaScript can hold mixed types

In most languages, an array must hold all the same type — all numbers, or all strings. JavaScript has no such rule:

```javascript
const mixed = [42, "hello", true, null, { name: "Priya" }, [1, 2, 3]];
```

Numbers, strings, booleans, null, objects, even other arrays — all in one array. JavaScript allows it completely.

This is powerful but dangerous. If you're not careful, you'll loop through an array expecting numbers and suddenly hit a string, and your math breaks silently. Always know what's actually inside your arrays.

## 2\. How to Create an Array

### The Main Way — Square Bracket Syntax

```javascript
const fruits  = ["apple", "banana", "mango"];
const marks   = [85, 90, 78, 92];
const tasks   = ["buy groceries", "do laundry", "study JS"];
const flags   = [true, false, true, true];
```

Square brackets, values separated by commas. That's all.

### An Empty Array — Also Valid

```javascript
const items = [];   // empty, add stuff later
```

### Storing an Array in Different Ways

```javascript
// const — you'll use this most often
const colors = ["red", "green", "blue"];

// let — when you might reassign the whole array later
let scores = [10, 20, 30];

// var — old way, avoid it
var names = ["Priya", "Rahul"];
```

Use `const` for arrays by default. You can still add, remove, and change items inside a `const` array — `const` only prevents you from reassigning the variable itself to a completely new array.

### 🔥 Gotcha #2 — There's another way to create arrays and it has a bizarre trap

JavaScript has a second way called `new Array()`. Most beginners never use it, but they encounter it and get confused:

```javascript
const arr = new Array(3);
console.log(arr);        // [ <3 empty items> ]
console.log(arr.length); // 3
```

You passed the number `3` and got an array with 3 empty slots — not an array containing the number 3. This is one of JavaScript's oldest design mistakes.

If you actually want an array containing the number 3:

```javascript
const arr = [3];         // just use square brackets
console.log(arr);        // [3]
console.log(arr.length); // 1
```

Avoid `new Array()` entirely. Square brackets are clearer, shorter, and don't have this trap.

### 🔥 Gotcha #3 — Trailing commas are valid and won't create an extra element

```javascript
const fruits = [
  "apple",
  "banana",
  "mango",   // ← trailing comma, totally fine
];

console.log(fruits.length);  // 3, not 4
```

JavaScript ignores the last comma. This is actually encouraged in modern code because it makes adding new items easier (you don't have to add a comma to the previous last line). Don't be alarmed when you see it.

## 3\. Accessing Elements Using Index

Every item in an array has a position number called an **index**. The first item is at index `0`, not `1`. This is the thing that trips up beginners most.

```javascript
const fruits = ["apple", "banana", "mango", "grapes", "orange"];
//                  0         1        2        3         4
```

To get an item, write the array name followed by the index in square brackets:

```javascript
console.log(fruits[0]);  // "apple"
console.log(fruits[1]);  // "banana"
console.log(fruits[2]);  // "mango"
console.log(fruits[4]);  // "orange"
```

### Why Does It Start at 0?

Because the index isn't really a "position number" — it's an **offset from the start**. The first item is 0 steps away from the beginning. The second item is 1 step away. It's a counting-from-zero system baked deep into how computers work.

Every major programming language does this. Burn it into your memory: **first item is index 0**.

### Getting the Last Item

If you have 5 items, the last item is at index 4 — always one less than the total count. The clean way to always get the last item regardless of array size:

```javascript
const fruits = ["apple", "banana", "mango", "grapes", "orange"];

console.log(fruits[fruits.length - 1]);  // "orange" — always the last item
```

`fruits.length` is 5. `5 - 1` is 4. `fruits[4]` is `"orange"`. Works no matter how many items are in the array.

### 🔥 Gotcha #4 — Accessing an index that doesn't exist returns `undefined`, not an error

javascript

```javascript
const fruits = ["apple", "banana", "mango"];

console.log(fruits[10]);   // undefined — no crash
console.log(fruits[-1]);   // undefined — no crash
console.log(fruits[999]);  // undefined — no crash
```

JavaScript never throws an error for out-of-range indexes. It just quietly returns `undefined`. This means you can write `fruits[10]` on a 3-item array and your code keeps running — silently using `undefined` somewhere downstream and eventually breaking in a confusing way far from the actual mistake.

Always double-check your index values when debugging unexpected `undefined` values.

### 🔥 Gotcha #5 — Negative indexes don't work like Python

If you've used Python, you know `arr[-1]` gives you the last item. **This does not work in JavaScript:**

```javascript
const fruits = ["apple", "banana", "mango"];

console.log(fruits[-1]);  // undefined ← not "mango"!
```

JavaScript returns `undefined` for negative indexes. The only modern way to use negative indexes in JavaScript is with the `.at()` method:

```javascript
console.log(fruits.at(-1));   // "mango" ✅
console.log(fruits.at(-2));   // "banana" ✅
```

`.at()` is newer (2022) but works in all modern browsers. For the last item, most developers still use `fruits[fruits.length - 1]` because it works everywhere.

## 4\. Updating Elements

Updating an element is simple — access it by index and assign a new value:

```javascript
const fruits = ["apple", "banana", "mango"];

fruits[1] = "strawberry";   // replace "banana" with "strawberry"

console.log(fruits);  // ["apple", "strawberry", "mango"]
```

The old value is gone. The new value takes its place.

You can update any index the same way:

```javascript
const marks = [85, 90, 78, 92, 88];

marks[2] = 95;   // student improved their score

console.log(marks);  // [85, 90, 95, 92, 88]
```

### 🔥 Gotcha #6 — `const` arrays can still be updated

This surprises everyone coming from other languages:

```javascript
const fruits = ["apple", "banana", "mango"];

fruits[0] = "pineapple";   // ✅ works fine
fruits[1] = "kiwi";        // ✅ works fine

console.log(fruits);  // ["pineapple", "kiwi", "mango"]
```

You declared it with `const` but still changed the contents. `const` only prevents you from reassigning the variable to a new array:

```javascript
fruits = ["grape", "peach"];   // ❌ TypeError — can't reassign a const variable
```

The variable `fruits` must always point to the same array. But that array's contents can be changed freely. Use `const` for arrays by default and don't let this confuse you.

### 🔥 Gotcha #7 — Assigning to an index beyond the array creates empty slots

This one is genuinely weird:

```javascript
const arr = ["a", "b", "c"];   // length 3

arr[6] = "g";   // assign to index 6, skipping 3, 4, 5

console.log(arr);         // ["a", "b", "c", empty × 3, "g"]
console.log(arr.length);  // 7
console.log(arr[3]);      // undefined
console.log(arr[4]);      // undefined
console.log(arr[5]);      // undefined
```

JavaScript doesn't throw an error. It creates a "sparse array" — an array with holes in it. Indexes 3, 4, and 5 exist but are empty. The length jumps to 7. These empty slots behave like `undefined` when accessed but behave inconsistently with array methods — some methods skip them, some don't.

Never intentionally assign to an index far beyond your array's current length. If you need to add to the end, there are proper methods for that.

## 5\. Array Length Property

`length` tells you how many items are in the array:

```javascript
const fruits = ["apple", "banana", "mango", "grapes", "orange"];

console.log(fruits.length);  // 5
```

It's not a method — no parentheses. It's a property. Just `.length`.

### Length Updates Automatically

As you add or remove items, `length` updates itself:

```javascript
const items = ["a", "b", "c"];
console.log(items.length);  // 3

items[3] = "d";
console.log(items.length);  // 4

items[4] = "e";
console.log(items.length);  // 5
```

You never have to manually track how many items are in your array. `length` always knows.

### 🔥 Gotcha #8 — You can manually set `length` and it destroys your array

This is something most developers don't know exists:

```javascript
const fruits = ["apple", "banana", "mango", "grapes", "orange"];

fruits.length = 3;   // manually shrink length to 3

console.log(fruits);  // ["apple", "banana", "mango"]
// "grapes" and "orange" are permanently gone
```

Setting `length` to a smaller number truncates the array. The items beyond the new length are deleted — not hidden, not moved. Gone.

Setting it to a larger number creates empty slots:

```javascript
fruits.length = 6;
console.log(fruits);   // ["apple", "banana", "mango", empty × 3]
```

Manually setting `length` is almost never what you actually want to do. The only common intentional use is clearing an array completely:

```javascript
fruits.length = 0;   // empties the array
console.log(fruits); // []
```

Some developers use this trick, but it confuses anyone reading the code. Creating a new empty array is clearer.

### 🔥 Gotcha #9 — `length` is not the same as the highest index + 1 in sparse arrays

Normally, `length` equals highest index + 1, which equals total number of items. In a sparse array, it's not:

```javascript
const arr = [];
arr[99] = "hello";

console.log(arr.length);  // 100 — not 1!
console.log(arr[0]);      // undefined — most slots are empty
```

You have one actual value but length is 100. This is why manually assigning to high indexes is dangerous — your length becomes misleading and looping through the array iterates over 99 empty slots before reaching your actual value.

## 6\. Looping Over Arrays

Looping means going through every item in the array one by one. This is where arrays become truly powerful — you can process 5 items or 5000 items with the exact same code.

### The Classic `for` Loop

```javascript
const fruits = ["apple", "banana", "mango", "grapes", "orange"];

for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}

// apple
// banana
// mango
// grapes
// orange
```

Breaking this down:

*   `let i = 0` — start at index 0
    
*   `i < fruits.length` — keep going as long as i is less than the total count
    
*   `i++` — move to the next index after each iteration
    
*   `fruits[i]` — access the item at the current index
    

This is the most fundamental loop. Understand every part of it.

### The `for...of` Loop — Cleaner for Simple Cases

When you just need each value and don't care about the index:

```javascript
const fruits = ["apple", "banana", "mango", "grapes", "orange"];

for (let fruit of fruits) {
  console.log(fruit);
}

// apple
// banana
// mango
// grapes
// orange
```

`for...of` gives you the value directly. No index variable. No `fruits[i]`. Cleaner to read when you just want to go through every item.

### When to Use Which Loop

Use the classic `for` loop when you need the index — for example, to print "Item 1: apple, Item 2: banana":

```javascript
for (let i = 0; i < fruits.length; i++) {
  console.log("Item " + (i + 1) + ": " + fruits[i]);
}

// Item 1: apple
// Item 2: banana
// Item 3: mango
// Item 4: grapes
// Item 5: orange
```

Use `for...of` when you only care about the values themselves.

### 🔥 Gotcha #10 — Looping with `for...in` on arrays works but is wrong

`for...in` is designed for objects. Technically it works on arrays, but it's the wrong tool and causes real problems:

```javascript
const fruits = ["apple", "banana", "mango"];

for (let key in fruits) {
  console.log(key);   // "0", "1", "2" — gives you indexes as STRINGS, not values
}
```

You get the indexes as strings, not the actual values. And if any library added something to `Array.prototype`, those extra properties show up in your loop too.

Always use `for` or `for...of` for arrays. Never `for...in`.

### 🔥 Gotcha #11 — Modifying an array while looping with `for...of` is dangerous

```javascript
const numbers = [1, 2, 3, 4, 5];

for (let num of numbers) {
  console.log(num);
  if (num === 3) {
    numbers.push(6);   // adding items while looping
  }
}
```

Adding items to an array while looping through it can cause unexpected behaviour — in some cases an infinite loop, in others skipped items. Modifying the array you're currently iterating is a recipe for subtle bugs. If you need to modify an array based on a loop, collect changes first and apply them after the loop is done.

* * *

### 🔥 Gotcha #12 — `for` loop condition using `<=` instead of `<` is a classic off-by-one error

This is one of the most common beginner bugs:

```javascript
const fruits = ["apple", "banana", "mango"];  // indexes 0, 1, 2

for (let i = 0; i <= fruits.length; i++) {   // ← <= instead of 
  console.log(fruits[i]);
}

// apple
// banana
// mango
// undefined  ← extra iteration at index 3, which doesn't exist
```

`fruits.length` is 3. With `<=`, the loop runs when `i` is 0, 1, 2, and 3. Index 3 doesn't exist — you get `undefined` on the last iteration. The condition must be `i < fruits.length`, not `i <= fruits.length`.

## Assignments — Do These Before Moving On

### Assignment 1 — Five Favourite Movies

```javascript
const movies = [
  "Inception",
  "Interstellar",
  "The Dark Knight",
  "3 Idiots",
  "Dil Chahta Hai"
];
```

### Assignment 2 — Print First and Last Element

```javascript
console.log(movies[0]);                    // "Inception"
console.log(movies[movies.length - 1]);    // "Dil Chahta Hai"
```

### Assignment 3 — Change One Value and Print Updated Array

```javascript
movies[2] = "Taare Zameen Par";

console.log(movies);
// ["Inception", "Interstellar", "Taare Zameen Par", "3 Idiots", "Dil Chahta Hai"]
```

### Assignment 4 — Loop and Print All Elements

```javascript
for (let i = 0; i < movies.length; i++) {
  console.log((i + 1) + ". " + movies[i]);
}

// 1. Inception
// 2. Interstellar
// 3. Taare Zameen Par
// 4. 3 Idiots
// 5. Dil Chahta Hai
```

### Bonus — Same Loop Using `for...of`

```javascript
for (let movie of movies) {
  console.log(movie);
}
```

* * *

## The 12 Gotchas Recap

Keep this list:

1.  Arrays can hold mixed types — numbers, strings, objects, other arrays all at once
    
2.  `new Array(3)` creates 3 empty slots, not an array containing 3 — use square brackets always
    
3.  Trailing commas are valid and don't add extra elements
    
4.  Accessing a missing index returns `undefined` silently — no error
    
5.  Negative indexes return `undefined` in JavaScript — use `.at(-1)` for last item
    
6.  `const` arrays can still have their contents updated — const only blocks reassignment
    
7.  Assigning to an index beyond the array's end creates empty "sparse" slots
    
8.  Manually setting `length` to a smaller number permanently deletes those elements
    
9.  In a sparse array, `length` doesn't equal actual number of items
    
10.  Never use `for...in` on arrays — use `for` or `for...of`
     
11.  Modifying an array while looping through it causes unpredictable behaviour
     
12.  Use `i < array.length` not `i <= array.length` — off-by-one is the most common loop bug
