Ytterligare funktioner för klasser i JavaScript
I denna artikel kommer vi att förklara de ytterligare funktionerna för klasser i JavaScript.
YouTube Video
Ytterligare funktioner för klasser i JavaScript
Privata egenskaper i JavaScript
I JavaScript är privata egenskaper sådana som endast är tillgängliga inom objektet eller klassen. Detta möjliggör en säkrare och mer robust koddesign genom att tillhandahålla kapsling, så att direkt modifiering eller referens från extern kod inte är möjlig.
Introducerades i ECMAScript 2020 (ES11) år 2020, användningen av #
(hash) för att definiera privata fält inom en klass infördes. Detta ger ett tydligare sätt, som ersätter traditionella JavaScript-konventioner för privata fält (såsom variabelnamn som börjar med ett understreck).
Fördelar med privata egenskaper
Följande är fördelarna med privata egenskaper.
- Inkapsling: Döljer det interna tillståndet från utsidan och bibehåller datakonsistens.
- Säkerhet: Förhindrar att egenskaper oavsiktligt ändras av extern kod.
- Förbättrad underhållbarhet: Döljer implementeringen av objekt eller klasser och klargör det gränssnitt som exponeras utåt.
Hur man använder privata egenskaper
Definiera privata egenskaper i klasser
Privata fält definieras med ett namn som börjar med #
. Detta fält kan inte direkt nås från instanser av klassen eller dess 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 ovan är #name
en privat egenskap som inte kan nås direkt utanför Person
-klassen. Du kan endast komma åt eller ändra namnet genom metoderna getName
och setName
.
Definiera privata metoder
Precis som privata egenskaper definieras även privata metoder med ett namn som börjar med #
. Privata metoder kan endast anropas inom 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
Här definieras #logCount
som en privat metod och kan inte nås utanför klassen. Denna metod används endast inom klassen.
Fördelar och överväganden med privata egenskaper
Fördel
- Eftersom det inte kan nås direkt utanför klassen förhindras oavsiktliga ändringar eller operationer.
- Eftersom delar som inte är synliga från utsidan kan döljas väl, kan du tydligt hantera de delar du exponerar som ett API.
Anteckningar
- Eftersom privata fält är helt dolda från utsidan av klassen kan testning och felsökning bli svåra. Därför är det viktigt att tillhandahålla ett API som kan testas grundligt i designfasen.
- Privata fält beter sig annorlunda än andra delar av JavaScript med prototypbaserade egenskaper eftersom de är unika för varje instans.
Traditionellt pseudonymt genomförande av privata egenskaper
Innan introduktionen av privata fält med #
hade JavaScript ingen officiell syntax för privata egenskaper. Därför implementerades pseudo-privata egenskaper tidigare på följande sätt.
Konvention av att använda understreck
Utvecklare indikerade konventionellt 'privat' genom att lägga till ett understreck före variabelnamn.
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)
Denna metod är endast en 'konvention', och i praktiken kan egenskaperna fortfarande nås från utsidan.
Implementering av privata egenskaper med hjälp av closures
Det är också möjligt att uppnå privata egenskaper genom att använda 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 denna metod är variabeln _name
innesluten inom funktionsscope och kan inte nås direkt från utsidan.
Sammanfattning
Privata egenskaper i JavaScript är mycket effektiva för att tillhandahålla kapsling i klass- och objektutformning, vilket hjälper till att skydda data säkert. Den #
-notation för privata fält som introducerades i ES2020 ger en tydligare och säkrare metod för hantering av integritet jämfört med traditionella konventioner och closures.
Optional Chaining i JavaScript
Optional Chaining är en mycket användbar syntax i JavaScript för att nå egenskaper hos djupt inbäddade objekt. Den förbättrar kodläsbarhet och underhållbarhet genom att tillåta säker åtkomst utan att behöva kontrollera förekomsten av specifika egenskaper individuellt.
Grundläggande syntax för Optional Chaining
Optional Chaining kan användas genom att placera ?
före punkten (.
) eller hakparentessyntaxen som används för att nå egenskaper. Denna notation returnerar undefined
när en traverserad egenskap är null
eller undefined
, vilket gör att programmet kan fortsätta bearbetningen säkert utan att generera ett fel.
Exempel:
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 detta exempel når vi address
och dess city
-egenskap hos user
-objektet. Utan att använda valfri kedjning skulle du behöva utföra flera existenskontroller, men med valfri kedjning kan du säkert få åtkomst till egenskapen med en enda sats.
Använda valfri kedjning med arrayer och funktioner
Valfri kedjning gäller inte bara för objektens egenskaper, utan även för arrayelement och funktionsanrop.
Exempel med arrayer:
1const users = [{ name: 'Alice' }, { name: 'Bob' }];
2
3// Accessing the non-existent third element
4const thirdUser = users[2]?.name;
5console.log(thirdUser); // undefined
Exempel 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
Kombinera valfri kedjning med standardvärden
När du använder valfri kedjning är det vanligt att använda den logiska ELLER-operatorn (||
) eller nullish sammanslagningsoperatorn (??
) för att ange standardvärden om en egenskap inte existerar.
Exempel:
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
||
-operatorn behandlar false
, 0
, ''
, etc., som falska, medan ??
-operatorn endast använder standardvärdet om operanden är null
eller undefined
.
Fördelar med valfri kedjning
- Säker åtkomst till nästlade objekt: Genom att använda valfri kedjning behöver du inte längre utföra explicita existenskontroller, vilket gör koden mer kortfattad.
- Undvikande av fel: Det kan förhindra körningsfel även om en egenskap är
null
ellerundefined
. - Förbättrad läsbarhet och underhållbarhet: Särskilt när man hanterar många nästlade objekt förbättras kodens läsbarhet avsevärt.
Försiktighet vid användning av valfri kedjning
- Frekvent användning av valfri kedjning kan vara ett tecken på att datastrukturens design är alltför komplex. Du bör sträva efter en enkel datamodell.
- Eftersom vissa äldre webbläsare och JavaScript-motorer inte stöder det kan du behöva använda polyfills eller transpilers.
Slutsats
Valfri kedjning är en kraftfull funktion som förenklar säker åtkomst till egenskaper och funktioner hos nästlade objekt i JavaScript. Det är särskilt effektivt vid åtkomst till djupt nästlade datastrukturer, vilket bidrar till att förebygga fel och förbättra kodens läsbarhet.
Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.