Yderligere funktioner i klasser i JavaScript
I denne artikel vil vi forklare de yderligere funktioner af klasser i JavaScript.
YouTube Video
Yderligere funktioner i klasser i JavaScript
Private egenskaber i JavaScript
I JavaScript er private egenskaber egenskaber, der kun er tilgængelige inden for objektet eller klassen. Dette muliggør mere sikker og robust kodning ved at tilbyde indkapsling, så direkte ændring eller reference fra ekstern kode ikke er mulig.
Introduceret i ECMAScript 2020 (ES11) i 2020, blev brugen af #
(hash) til at definere private felter inden for en klasse introduceret. Dette giver en mere tydelig metode, der erstatter traditionelle JavaScript-konventioner for private (som f.eks. variabelnavne, der starter med en understregning).
Fordele ved private egenskaber
Følgende er fordelene ved private egenskaber.
- Indkapsling: Skjuler intern tilstand fra omverdenen og opretholder datakonsistens.
- Sikkerhed: Forhindrer egenskaber i at blive utilsigtet ændret af ekstern kode.
- Forbedret vedligeholdelse: Skjuler implementeringen af objekter eller klasser og præciserer grænsefladen, der eksponeres til omverdenen.
Sådan bruger du private egenskaber
Definere private egenskaber i klasser
Private felter defineres ved at bruge et navn, der starter med #
. Dette felt kan ikke tilgås direkte fra instanser af klassen eller dens underklasser.
1class Person {
2 // Define private property
3 #name;
4
5 constructor(name) {
6 this.#name = name;
7 }
8
9 // Method to access the private property
10 getName() {
11 return this.#name;
12 }
13
14 // Method to change the private property
15 setName(newName) {
16 this.#name = newName;
17 }
18}
19
20const john = new Person("John");
21console.log(john.getName()); // John
22
23// Cannot access private property directly
24console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class
I koden ovenfor er #name
en privat egenskab, der ikke kan tilgås direkte uden for Person
-klassen. Du kan kun få adgang til eller ændre navnet gennem metoderne getName
og setName
.
Definere private metoder
Ligesom private egenskaber defineres private metoder også ved hjælp af et navn, der starter med #
. Private metoder kan kun kaldes fra inden for klassen.
1class Counter {
2 #count = 0;
3
4 increment() {
5 this.#count++;
6 this.#logCount(); // Calling private method
7 }
8
9 // Private method
10 #logCount() {
11 console.log(`Current count: ${this.#count}`);
12 }
13}
14
15const counter = new Counter();
16counter.increment(); // Current count: 1
17
18// Cannot access private method directly
19counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class
Her er #logCount
defineret som en privat metode og kan ikke tilgås uden for klassen. Denne metode bruges kun inden for klassen.
Fordele og overvejelser ved private egenskaber
Fordel
- Fordi det ikke kan tilgås direkte uden for klassen, forhindres utilsigtede ændringer eller operationer.
- Fordi dele, der ikke er synlige udefra, kan skjules effektivt, kan du tydeligt administrere de dele, du eksponerer som en API.
Noter
- Fordi private felter er fuldstændig skjult uden for klassen, kan testning og fejlfinding blive vanskelig. Derfor er det vigtigt at levere en API, der kan testes grundigt på designstadiet.
- Private felter opfører sig anderledes end andre dele af JavaScript med prototypebaserede karakteristika, fordi de er unikke for hver forekomst.
Traditionel pseudonym implementering af private egenskaber
Før introduktionen af private felter med #
, havde JavaScript ikke en officiel syntaks for private egenskaber. Derfor blev pseudo-private egenskaber tidligere implementeret på følgende måder.
Konventionen om at bruge understregningstegn
Udviklere angav konventionelt 'private' ved at foranstille variabelnavne med et understregningstegn.
1class Car {
2 constructor(brand) {
3 this._brand = brand; // Using an underscore to indicate private
4 }
5
6 getBrand() {
7 return this._brand;
8 }
9}
10
11const car = new Car("Toyota");
12console.log(car.getBrand()); // Toyota
13console.log(car._brand); // Toyota (Accessible from outside)
Denne metode er blot en 'konvention', og i praksis kan egenskaberne stadig tilgås udefra.
Implementering af private egenskaber ved hjælp af closures
Det er også muligt at opnå private egenskaber ved hjælp af closures med funktionsscope.
1function createPerson(name) {
2 let _name = name; // Private variable within function scope
3
4 return {
5 getName: function() {
6 return _name;
7 },
8 setName: function(newName) {
9 _name = newName;
10 }
11 };
12}
13
14const person = createPerson("Alice");
15console.log(person.getName()); // Alice
16person.setName("Bob");
17console.log(person.getName()); // Bob
18
19// Cannot access directly from outside
20console.log(person._name); // undefined
Med denne metode er variablen _name
indkapslet i funktionsscopet og kan ikke tilgås direkte udefra.
Sammendrag
Private egenskaber i JavaScript er meget effektive til at sikre indkapsling i klasse- og objekt-design og bidrager til at beskytte data sikkert. Notationen #
for private felter, som blev introduceret i ES2020, giver en klarere og mere sikker metode til privatlivsforvaltning sammenlignet med traditionelle konventioner og closures.
Optional Chaining i JavaScript
Optional Chaining er en meget nyttig syntaks i JavaScript til at tilgå egenskaber i dybt indlejrede objekter. Det forbedrer læsbarhed og vedligeholdelse af kode ved at tillade sikker adgang uden at skulle tjekke individuelt for eksistensen af specifikke egenskaber.
Grundlæggende syntaks for Optional Chaining
Optional Chaining kan bruges ved at placere ?
før punktumet (.
) eller firkantet parentes-syntaks, der bruges til egenskabsadgang. Denne notation returnerer undefined
, når en gennemløbet egenskab er null
eller undefined
, hvilket tillader programmet at fortsætte sikkert uden at kaste en fejl.
Eksempel:
1const user = {
2 name: 'John',
3 address: {
4 street: '123 Main St',
5 city: 'New York'
6 }
7};
8
9// Without using optional chaining
10const city = user && user.address && user.address.city;
11console.log(city); // New York
12
13// Using optional chaining
14const cityWithOptionalChaining = user?.address?.city;
15console.log(cityWithOptionalChaining); // New York
I dette eksempel tilgår vi address
og dens city
-egenskab i user
-objektet. Uden at bruge optional chaining, ville du skulle udføre flere eksistenskontroller, men med optional chaining kan du sikkert tilgå egenskaben med en enkelt udtalelse.
Brug af Optional Chaining med arrays og funktioner
Optional chaining kan anvendes ikke kun på objekt-egenskaber, men også på array-elementer og funktionskald.
Eksempel med arrays:
1const users = [{ name: 'Alice' }, { name: 'Bob' }];
2
3// Accessing the non-existent third element
4const thirdUser = users[2]?.name;
5console.log(thirdUser); // undefined
Eksempel med funktioner:
1const user = {
2 greet: function() {
3 return 'Hello!';
4 }
5};
6
7// Call the function only if greet exists
8const greeting = user.greet?.();
9console.log(greeting); // Hello!
10
11// Return undefined if greet does not exist
12const nonExistentGreeting = user.nonExistentMethod?.();
13console.log(nonExistentGreeting); // undefined
Kombination af Optional Chaining med standardværdier
Når man bruger optional chaining, er det almindeligt at bruge den logiske OR-operator (||
) eller nullish coalescing-operatoren (??
) til at angive standardværdier, hvis en egenskab ikke findes.
Eksempel:
1const user = {
2 name: 'John',
3 address: {
4 city: 'New York'
5 }
6};
7
8// Set a default value for a non-existent property
9const state = user?.address?.state || 'Unknown';
10console.log(state); // Unknown
11
12// Example using the nullish coalescing operator
13const zipCode = user?.address?.zipCode ?? '00000';
14console.log(zipCode); // 00000
Operatoren ||
betragter false
, 0
, ''
, osv. som falske, mens operatoren ??
kun bruger standardværdien, hvis operanden er null
eller undefined
.
Fordele ved Optional Chaining
- Sikker adgang til indlejrede objekter: Ved at bruge optional chaining behøver du ikke længere udføre eksplicitte eksistenskontroller, hvilket gør koden mere koncis.
- Undgåelse af fejl: Det kan forhindre runtime-fejl, selv hvis en egenskab er
null
ellerundefined
. - Forbedret læsbarhed og vedligeholdelse: Især når man arbejder med mange indlejrede objekter, forbedres kodens læsbarhed markant.
Forsigtighed med Optional Chaining
- Hyppig brug af optional chaining kan være et tegn på, at datastrukturens design er unødigt komplekst. Du bør stræbe efter en simpel datamodel.
- Da nogle ældre browsere og JavaScript-motorer ikke understøtter det, kan det være nødvendigt at bruge polyfills eller transpilers.
Konklusion
Optional chaining er en kraftfuld funktion, der forenkler sikker adgang til egenskaber og funktioner af indlejrede objekter i JavaScript. Det er særligt effektivt, når man tilgår dybt indlejrede datastrukturer, hvilket bidrager til fejlfri kode og forbedret læsbarhed.
Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.