Muterbar og Ikke-muterbar i JavaScript

Muterbar og Ikke-muterbar i JavaScript

Denne artikkelen forklarer konseptene om muterbar og ikke-muterbar i JavaScript.

YouTube Video

Muterbar og Ikke-muterbar i JavaScript

Hva er Muterbar?

Muterbar betyr at en verdi kan endres. Objekter og arrayer, som er referansetyper, er typiske eksempler på muterbare datastrukturer.

Eksempel på et Muterbart Objekt

1let person = { name: "Alice", age: 25 };
2person.age = 26;
3console.log(person); // { name: "Alice", age: 26 }

I denne koden endres age-egenskapen til person-objektet fra 25 til 26. Siden objekter sendes som referanse, blir innholdet ved minneadressen lagret i person-variabelen endret.

Eksempel på en Muterbar Array

1let numbers = [1, 2, 3];
2numbers.push(4);
3console.log(numbers); // [1, 2, 3, 4]

I denne koden brukes push-metoden for å legge til et nytt element 4 til den originale arrayen. Dette endrer den originale arrayen, og gjør det til en muterbar operasjon.

Eksempel i en Funksjon

 1// Function to append a value to an array
 2function append(arr, value) {
 3    arr.push(value); // Modify the original array
 4    console.log(arr);
 5}
 6
 7let numbers = [1, 2, 3];
 8append(numbers, 4);
 9
10console.log(numbers); // [1, 2, 3, 4] (original array is modified)

Når man utfører muterbare operasjoner inne i en funksjon, blir den originale arrayen også endret.

Hva er Ikke-muterbar?

Ikke-muterbar betyr at en verdi ikke kan endres. Primitive typer er fundamentalt sett ikke-muterbare.

Eksempel på en Ikke-muterbar Primitiv Type

1let str = "hello";
2str[0] = "H";
3console.log(str); // "hello"

Forsøk på å endre den første bokstaven i strengen str til H mislykkes fordi strenger er ikke-muterbare.

Eksempel i en Funksjon

 1// Function to increment a number
 2function increment(num) {
 3    num++; // This modifies only the local copy of num
 4    console.log(num);
 5}
 6
 7let number = 10;
 8increment(number);
 9
10console.log(number); // 10 (original number remains unchanged)

Siden tall er ikke-muterbare, påvirker ikke operasjoner inne i en funksjon den originale variabelen.

Ikke-muterbare Operasjoner på Arrayer

Arrayer er muterbare, men å opprette en ny array i stedet for å endre den originale tillater ikke-muterbare operasjoner.

1// Create an array of numbers
2let numbers = [1, 2, 3];
3
4// Create a new array by spreading the original and adding a new element
5let newNumbers = [...numbers, 4];
6
7console.log(numbers); // [1, 2, 3] (original array is unchanged)
8console.log(newNumbers); // [1, 2, 3, 4] (new array with an added element)

Her brukes spredningssyntaksen (...) for å lage et nytt array newNumbers. Siden det opprinnelige numbers arrayet ikke endres, er dette en uforanderlig operasjon.

Fordeler med å bruke uforanderlige datastrukturer

Forbedret forutsigbarhet

Siden uforanderlige data ikke kan endres, er uventede modifikasjoner mindre sannsynlige, noe som reduserer risikoen for feil.

Kompatibilitet med biblioteker basert på uforanderlighet

Biblioteker som React og Redux er ofte designet med uforanderlige data i tankene, noe som gjør tilstandshåndtering enklere når det brukes riktig.

Gjør objekter uforanderlige med Object.freeze

Object.freeze kan brukes for å forhindre modifikasjoner av et objekt.

1// Create a frozen object (properties cannot be modified)
2const person = Object.freeze({ name: "Alice", age: 25 });
3
4// Attempt to modify a property (ignored in non-strict mode, error in strict mode)
5person.age = 26;
6
7console.log(person); // { name: "Alice", age: 25 }

Men Object.freeze utfører en overfladisk frysing, noe som betyr at egenskapene til nestede objekter forblir endringsbare.

1// Create a frozen object with a nested object
2const user = Object.freeze({ profile: { name: "Bob" } });
3
4// Attempt to modify a nested property (this works because Object.freeze() is shallow)
5user.profile.name = "Charlie";
6
7console.log(user.profile.name); // "Charlie" (nested object is still mutable)

For å lage et fullstendig uforanderlig objekt, kreves en dyp frysing.

 1// Function to deeply freeze an object, making all nested objects immutable
 2function deepFreeze(obj) {
 3  Object.keys(obj).forEach(key => {
 4    if (typeof obj[key] === "object" && obj[key] !== null) {
 5      deepFreeze(obj[key]); // Recursively freeze nested objects
 6    }
 7  });
 8  return Object.freeze(obj); // Freeze the top-level object
 9}
10
11// Create a deeply frozen object
12const user = deepFreeze({ profile: { name: "Bob" } });
13
14// Attempt to modify a nested property (ignored)
15user.profile.name = "Charlie";
16
17console.log(user.profile.name); // "Bob" (unchanged due to deep freeze)

Sammendrag

  • Endringsbare data kan modifiseres, inkludert objekter og array.
  • Uforanderlige data kan ikke modifiseres, inkludert primitive typer som strenger og tall.
  • Bruk av spredningssyntaks eller map muliggjør uforanderlige dataoperasjoner..
  • Object.freeze og deepFreeze kan brukes for å forhindre modifikasjoner av objekter.
  • Bruk av uforanderlige data gir mer forutsigbar og mindre feilutsatt kode.

Uforanderlig design forbedrer kodesikkerhet og lesbarhet, så bruk det godt!

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video