# Native JavaScript - Data Structures

## Variables in JavaScript

Variables in JavaScript are containers for storing data values. They allow you to store, modify, and use information throughout your program, such as numbers, text, or more complex data types[1](https://www.w3schools.com/js/js_variables.asp)[5](https://www.javascript.com/learn/variables)[6](https://javascript.info/variables).

### Declaring Variables

You can declare variables in JavaScript in several ways:

* **Automatically** (not recommended):

  ```javascript
  x = 5;
  ```

  This creates a global variable if not declared inside a function, but it’s considered bad practice
* **Using `var`**:

  ```javascript
  var x = 5;
  ```

  `var` is function-scoped and was the traditional way to declare variables before ES6
* **Using `let`**:

  ```javascript
  let y = 6;
  ```

  `let` is block-scoped and is preferred for variables that may change their value
* **Using `const`**:

  ```javascript
  const PI = 3.14;
  ```

  `const` is block-scoped and used for variables whose values should not change

### Assigning Values

You can assign a value to a variable either when you declare it or later in your code:

```javascript
let carName;
carName = "Volvo";
```

Or in one line:

```javascript
let carName = "Volvo";
```

Variables can be updated (except those declared with `const`)

### Naming Rules

* Variable names can contain letters, digits, underscores (\_), and dollar signs ($).
* Names must begin with a letter, underscore, or dollar sign.
* Names are case-sensitive (`myVar` and `myvar` are different).
* Reserved keywords (like `function` or `class`) cannot be used as variable names

### Example

```javascript
let user = 'John';
let age = 25;
let message = 'Hello';
```

You can use these variables elsewhere in your code:

```javascript
console.log(message); // Output: Hello
```

Variables can also be reassigned (except `const`):

```javascript
let weather = "rainy";
weather = "sunny";
console.log(weather); // Output: sunny
```

### Summary Table

| Keyword | Scope    | Can Reassign | Can Redeclare | Use Case                       |
| ------- | -------- | ------------ | ------------- | ------------------------------ |
| var     | Function | Yes          | Yes           | Old code, function-scoped vars |
| let     | Block    | Yes          | No            | Variables that change          |
| const   | Block    | No           | No            | Constants (unchanging values)  |

### Best Practices

* Always declare variables before using them.
* Prefer `let` and `const` over `var` in modern code.
* Use `const` by default, and only use `let` if the variable’s value will change

Variables are fundamental in JavaScript, enabling you to store and manage data efficiently throughout your programs.

## Mutable and Immutable Data Structures in JavaScript

**Mutable** and **immutable** are core concepts in JavaScript that describe whether a data structure can be changed after it is created.

### **Mutable Data Structures**

* **Definition:** Mutable data structures can be changed in place. Modifying them alters the original value in memory.
* **Examples:**
  * **Objects:** You can add, remove, or change properties directly.

    ```javascript
    let person = { name: 'Alice', age: 25 };
    person.age = 26; // The original object is modified
    ```
  * **Arrays:** You can update elements or change the array’s length.

    ```javascript
    let arr = [1, 2, 3];
    arr.push(4); // The original array is changed to [1, 2, 3, 4]
    ```
* **Use Cases:** Useful when you need to update data frequently or manage large, dynamic collections

### **Immutable Data Structures**

* **Definition:** Immutable data structures cannot be changed after creation. Any "modification" creates and returns a new structure, leaving the original unchanged.
* **Examples:**
  * **Primitive Types:** Strings, numbers, booleans, null, undefined, BigInt, and Symbol are all immutable.

    ```javascript
    let str = "hello";
    let newStr = str.toUpperCase(); // str remains "hello", newStr is "HELLO"
    ```

    ```javascript
    let num = 5;
    let newNum = num + 1; // num is still 5, newNum is 6
    ```
* **Immutability for Objects/Arrays:** By default, objects and arrays are mutable, but you can make them immutable using techniques like `Object.freeze()` or libraries such as Immutable.js.

  ```javascript
  const frozenObj = Object.freeze({ name: 'Bob' });
  // frozenObj.name = 'Alice'; // This will not change the object
  ```
* **Use Cases:** Immutability is favored for predictable state management, easier debugging, safer concurrency, and functional programming patterns

### **Comparison Table**

| Data Structure  | Mutable? | Example of Change    | Result                              |
| --------------- | -------- | -------------------- | ----------------------------------- |
| Object          | Yes      | `obj.age = 31`       | Alters original object              |
| Array           | Yes      | `arr.push(4)`        | Alters original array               |
| String          | No       | `str = 'H'`          | No effect; must create a new string |
| Number          | No       | `num += 1`           | Creates a new value                 |
| Object (frozen) | No       | `Object.freeze(obj)` | Cannot alter properties             |

### **Key Points**

* **All primitive types are immutable**: Strings, numbers, booleans, null, undefined, BigInt, and Symbol
* **Objects and arrays are mutable by default**: Their contents can be changed after creation
* **Immutability can be enforced**: Use `Object.freeze()` or third-party libraries for immutable collections
* **Immutability leads to safer, more predictable code**: Especially useful in functional programming and state management

**Summary:**

* Use mutable structures (objects, arrays) when in-place updates are needed and performance is critical.
* Prefer immutable structures (primitives, frozen objects, or immutable libraries) for safer, more predictable code, especially in concurrent or functional programming scenarios

## Array in JavaScript

**Arrays** in JavaScript are special objects used to store ordered collections of data. They can hold multiple values—of any type—within a single variable, making them a fundamental and versatile data structure in JavaScript

### **Key Features of Arrays**

* **Ordered Collection:** Elements are stored in a specific sequence and accessed by their index (starting from 0)
* **Flexible Data Types:** Arrays can contain numbers, strings, objects, other arrays (nested arrays), or any mix of these types
* **Mutable:** Arrays are mutable, meaning their contents can be changed after creation (add, remove, or update elements)
* **Dynamic Size:** Arrays can grow or shrink in size as elements are added or removed

### **Creating Arrays**

You can create arrays using:

* **Array Literal Syntax (most common):**

  ```javascript
  const fruits = ["Apple", "Banana", "Cherry"];
  ```
* **Array Constructor:**

  ```javascript
  const numbers = new Array(10, 20, 30);
  const emptyArray = new Array(5); // Creates an array with 5 empty slots
  ```
* **Mixed Data Types:**

  ```javascript
  const mixedArray = ["work", 1, true];
  ```

### **Accessing and Modifying Elements**

* **Access by Index:**

  ```javascript
  console.log(fruits[0]); // "Apple"
  ```
* **Update by Index:**

  ```javascript
  fruits[1] = "Blueberry"; // ["Apple", "Blueberry", "Cherry"]
  ```
* **Array Length:**

  ```javascript
  console.log(fruits.length); // 3
  ```

### **Common Array Methods**

| Method       | Description                                              | Example                                 |
| ------------ | -------------------------------------------------------- | --------------------------------------- |
| `push()`     | Add element to end                                       | `fruits.push("Date")`                   |
| `pop()`      | Remove element from end                                  | `fruits.pop()`                          |
| `shift()`    | Remove element from start                                | `fruits.shift()`                        |
| `unshift()`  | Add element to start                                     | `fruits.unshift("Apricot")`             |
| `slice()`    | Returns a shallow copy of a portion of the array         | `fruits.slice(1, 3)`                    |
| `concat()`   | Joins two or more arrays                                 | `fruits.concat(["Date", "Elderberry"])` |
| `includes()` | Checks if array contains a value                         | `fruits.includes("Apple")`              |
| `map()`      | Creates a new array by applying a function to each value | `fruits.map(fruit => fruit + " Pie")`   |

Arrays also support advanced operations like flattening nested arrays, filtering, and reducing

### **Nested Arrays**

Arrays can contain other arrays as elements, creating multidimensional structures:

```javascript
const nested = ["apple", ["banana", "cherry"]];
console.log(nested[1][0]); // "banana"
```

### **Summary Table**

| Feature           | Description                                             |
| ----------------- | ------------------------------------------------------- |
| Ordered           | Yes (indexed from 0)                                    |
| Data Types        | Any (numbers, strings, objects, arrays, etc.)           |
| Mutable           | Yes (elements can be added, removed, or changed)        |
| Creation Methods  | Array literal `[]`, `new Array()` constructor           |
| Common Operations | Access, update, add, remove, iterate, search, transform |

Arrays are a core part of JavaScript programming, providing an efficient way to store, organize, and manipulate collections of data

## Set in JavaScript

A **Set** in JavaScript is a built-in data structure introduced in ES6 that stores a collection of unique values. Unlike arrays, Sets automatically ensure that no duplicate values are present—each value can occur only once in a Set

### **Key Features of Set**

* **Unique Values Only:** Any value added to a Set that already exists is ignored; duplicates are not allowed
* **Any Data Type:** Sets can store values of any type—primitives or object references
* **Insertion Order:** Elements in a Set are iterated in the order they were inserted
* **Efficient Operations:** Sets provide fast access, insertion, and deletion, typically with O(1) time complexity due to internal hash table or search tree implementations

### **Creating a Set**

You can create a Set in two main ways:

```javascript
// Create an empty Set
const mySet = new Set();

// Create a Set from an array (duplicates are removed)
const numbers = new Set([1, 2, 3, 3, 4]); // Set contains 1, 2, 3, 4
```

### **Common Set Methods**

| Method          | Description                               | Example                     |
| --------------- | ----------------------------------------- | --------------------------- |
| `add(value)`    | Adds a value to the Set                   | `mySet.add(5)`              |
| `delete(value)` | Removes a value from the Set              | `mySet.delete(2)`           |
| `has(value)`    | Checks if a value exists in the Set       | `mySet.has(3)`              |
| `size`          | Returns the number of elements in the Set | `mySet.size`                |
| `clear()`       | Removes all elements from the Set         | `mySet.clear()`             |
| `forEach()`     | Iterates over each value in the Set       | `mySet.forEach(val => ...)` |

You can also iterate over a Set using a `for...of` loop:

```javascript
for (const value of mySet) {
  console.log(value);
}
```

### **When to Use a Set**

* When you need to store a collection of unique values.
* When you want fast checks for the presence of a value.
* When you need to eliminate duplicates from an array

### **Example Usage**

```javascript
const fruits = new Set();
fruits.add('apple');
fruits.add('banana');
fruits.add('apple'); // Duplicate, will be ignored

console.log(fruits); // Set { 'apple', 'banana' }
console.log(fruits.has('banana')); // true
console.log(fruits.size); // 2
```

## Map in JavaScript

A **Map** in JavaScript is a built-in data structure that stores key-value pairs, where each key is unique and can be of any data type—including objects, functions, and primitive values. Maps were introduced in ES6 and are designed to provide efficient and flexible key-based data storage and retrieval

### **Key Features of Map**

* **Unique Keys:** Each key in a Map must be unique; duplicate keys are not allowed.
* **Any Data Type as Key:** Unlike plain objects (which only allow strings and symbols as keys), Maps allow keys of any type, including objects, arrays, and functions
* **Insertion Order:** Maps maintain the order of elements based on the sequence in which they were added. Iterating over a Map will yield entries in their original insertion order
* **Size Property:** The `size` property returns the number of key-value pairs in the Map
* **Direct Iteration:** Maps are directly iterable, making it easy to loop over keys, values, or entries

### **Creating a Map**

```javascript
// Create an empty Map
const myMap = new Map();

// Create a Map from an array of key-value pairs
const anotherMap = new Map([
  ['name', 'Alice'],
  ['age', 30],
  ['city', 'Delhi']
]);
```

### **Adding and Modifying Entries**

```javascript
myMap.set('color', 'blue');
myMap.set(42, 'answer');
myMap.set({ id: 1 }, 'objectKey');
```

* The `set(key, value)` method adds or updates a key-value pair

### **Accessing Values**

```javascript
console.log(myMap.get('color')); // 'blue'
```

* The `get(key)` method retrieves the value associated with a key

### **Checking for Keys**

```javascript
myMap.has(42); // true
```

* The `has(key)` method checks if a key exists in the Map

### **Removing Entries**

```javascript
myMap.delete('color'); // Removes the key 'color'
myMap.clear();         // Removes all entries from the Map
```

* Use `delete(key)` to remove a specific entry and `clear()` to remove all entries

### **Getting the Size**

```javascript
myMap.size; // Number of key-value pairs
```

### **Iterating Over a Map**

You can iterate over a Map’s entries, keys, or values:

```javascript
for (const [key, value] of myMap) {
  console.log(key, value);
}

for (const key of myMap.keys()) {
  console.log(key);
}

for (const value of myMap.values()) {
  console.log(value);
}
```

### **When to Use Map**

* When you need to use objects or other non-string types as keys.
* When you require guaranteed insertion order.
* When you need frequent additions and removals of key-value pairs with efficient performance

## Array vs Map vs Set in JavaScript

JavaScript provides several built-in data structures for storing and managing collections of data. The most commonly used are **Array**, **Map**, and **Set**. Each has distinct characteristics and is best suited for specific use cases.

### **Comparison Table**

| Feature         | Array                                               | Map                                                | Set                                                |
| --------------- | --------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- |
| Structure       | Ordered list of values (indexed)                    | Collection of key-value pairs                      | Unordered collection of unique values              |
| Key/Index       | Integer indices (0, 1, 2, ...)                      | Any data type as key                               | No keys; only values                               |
| Value Types     | Any                                                 | Any                                                | Any                                                |
| Duplicates      | Allowed                                             | Keys must be unique                                | Not allowed (all values unique)                    |
| Order           | Maintains insertion order                           | Maintains insertion order                          | Maintains insertion order                          |
| Access          | By index (e.g., arr)                                | By key (e.g., map.get(key))                        | By value (e.g., set.has(value))                    |
| Iteration       | `for`, `forEach`, `for...of`                        | `forEach`, `for...of` (entries/keys/values)        | `forEach`, `for...of`                              |
| Common Use Case | Lists, arrays of data, ordered items                | Fast key-value lookup, dynamic keys                | Unique values, removing duplicates                 |
| Performance     | Fast random access by index; slower search by value | Fast key-based access (O(1)), efficient add/remove | Fast existence checks (O(1)), efficient add/remove |
| Example         | `[1][2][3]`                                         | `new Map([[1, 'a'], [2, 'b']])`                    | `new Set([1,[2][3])`                               |

### **When to Use Each**

* **Array**
  * Use when you need an ordered list of items, possibly with duplicates, and access by position (index) is important.
  * Example: List of user IDs, ordered tasks, etc.
* **Map**
  * Use when you need to associate unique keys (of any type) with values, and require fast lookup, insertion, or deletion by key.
  * Example: Storing user data by user ID, caching, dictionaries
* **Set**
  * Use when you need to store unique values and quickly check for existence, or when you want to remove duplicates from a collection.
  * Example: Unique tags, filtering duplicates from an array

### **Key Differences Explained**

* **Arrays** are best for ordered collections where the position of each element matters and duplicates are allowed.
* **Maps** are optimized for storing key-value pairs, where keys can be any data type and are unique. They provide efficient, direct access to values via keys
* **Sets** automatically enforce uniqueness among their values and are ideal for collections where duplicates should be eliminated or prevented

### **Summary**

* **Array:** Ordered, indexed, allows duplicates.
* **Map:** Key-value pairs, unique keys, any type as key, efficient lookups.
* **Set:** Unique values only, fast existence checks, no key-value pairs.

Choosing the right data structure depends on your specific requirements for ordering, uniqueness, and how you intend to access or modify the data


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sai11101989.gitbook.io/iss_workbook/web-technologies/native-javascript-data-structures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
