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
ogdeepFreeze
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.