7 obligatorische JavaScript-Funktionen

16.05.2024
Von 
Matthew Tyson ist Java-Entwickler und schreibt unter anderem für unsere US-Schwesterpublikation Infoworld.com.
Geht es um JavaScript, sollten Entwickler nicht nur forEach, map und substring aus dem Effeff beherrschen.
Diese Grundzutaten sollten Entwickler in petto haben, damit JavaScript seine Magie entfalten kann.
Diese Grundzutaten sollten Entwickler in petto haben, damit JavaScript seine Magie entfalten kann.
Foto: Maksym Fesenko | shutterstock.com

Suchmaschinen-Statistiken zeigen, dass Entwickler sieben JavaScript-Features gehäuft nachschlagen. Die reichen für sich allein zwar nicht aus, um komplette Programme zu schreiben - aber ohne sie geht es auch nicht. Im Folgenden lesen Sie, welche sieben grundlegenden Sprachfunktionen ins Toolkit eines jeden JavaScript-Entwicklers gehören - egal ob Anfänger oder Silverback.

1. array

Value Collections sind ein zentraler Aspekt aller Programmiersprachen. Im Fall von JavaScript kommen Arrays zum Einsatz, um solche Sammlungen zu speichern. Dabei sind JavaScript-Arrays dank des dynamischen Typisierungssystems der Sprache hochflexibel. Sie können ein leeres Array deklarieren - oder eines, das bereits Werte enthält:

// make a new empty array:

const myArray = [];

//add a value:

myArray.push("Happy New Year");

console.log(myArray[0]); // outputs "Happy New Year"

// make an array with values:

const myOtherArray = [0, "test", true];

Wie in den meisten anderen Sprachen sind Arrays in JavaScript "base 0". Soll heißen, das erste Element weist einen Index von 0 statt 1 auf. Darüber hinaus sehen Sie in obigem Beispiel auch, dass myOtherArray diverse Types enthalten kann - Zahlen, Strings oder Boolesche Werte.

2. for

Der for-Loop ist ebenfalls elementarer Bestandteil aller Programmiersprachen. Allerdings bringt dieses Element in JavaScript einige Besonderheiten mit. Die grundlegende Syntax des for-Loops sieht folgendermaßen aus:

for (let i = 0; i < 10; i++){

console.log("i is going up: "+ i);

}

Übersetzt in natürliche Sprache bedeutet dieser Code: "Gib mir eine Variable namens i und erledige, was in den geschweiften Klammern angegeben ist - insofern der Wert kleiner ist als 10. Füge dabei bei jedem Vorgang i eine 1 hinzu". Hierbei handelt es sich um eine gängige Loop-Variable, wobei "i" für "Iterator" steht.

Bei dieser Form spricht man von einem deklarativen Loop. Dieser ist äußerst flexibel, weil jeder Teil diverse Variationen aufweisen kann:

// This will loop forever, unless something else changes i, because i is not modified by the loop

for (let i = 0; i < 10;){

console.log("i is going up: "+ i);

}

// you can declare multiple variables, tests and modifiers at once

for (let i = 0, j = 10; i * j < 80 && i < 10; i++, j=j+5){

console.log(i * j); // outputs 0, 15, 40, 75 and breaks

}

Insbesondere bei komplexen und verschachtelten Loop-Konstruktionen kann es hilfreich sein, aussagekräftige(re) Iteratoren wie userIterator oder productCounter einzusetzen.

Darüber hinaus existiert in JavaScript auch ein for-in-Loop, der nützlich ist, wenn es um Schleifen in Zusammenhang mit JSON-Objekten geht:

let myObject = { foo: "bar", test: 1000 }

for (let x in myObject) {

for (let x in myObject) { console.log(x + "=" + myObject[x]) }

}

// outputs: foo=bar test=1000

Zudem lässt sich for-in auch für Arrays verwenden:

let arr = [5, 10, 15, 20];

for (let x in arr2) {

console.log(x + "=" + arr2[x]);

}

// outputs: 0=5, 1=10, 2=15, 3=20

Bei Objekten dient der Iterator (x) als Property-Name, in einem Array wird er zum Index. Letzterer kann dazu genutzt werden, um auf die Properties und Elemente von Objekten oder Arrays zuzugreifen.

3. forEach

Modernes JavaScript verschreibt sich der funktionalen Programmierung und die forEach-Funktion ist dafür ein hervorragendes Beispiel: Es handelt sich um eine simple, funktionale Methode, um über Sammlungen zu iterieren. Sie hält die gesamte Logik fest und macht fremde Iteratorvariablen (wie bei for) überflüssig.

arr.forEach((x) => { console.log (x) })

// outputs: 5, 10, 15, 20

In diesem Beispiel haben wir eine Funktion an forEach übergeben und eine anonyme Inline-Funktion mit der Pfeil-Syntax definiert. Dabei werden Sie feststellen, dass die in forEach exponierte Variable (in diesem Fall x), tatsächlich den Wert des Elements erhält, nicht den des Index.

Es gibt noch einen weiteren einfachen Weg zu einem Iterator, der dasselbe Verhalten aufweist:

arr.forEach((x, i) => { console.log (i + "=" + x) })

// outputs 0=5, 1=10, 2=15, 3=20

Auch die simplifizierte Pfeil-Syntax in Kombination mit forEach ist gängig:

arr2.forEach(x => console.log(x))

Diese Syntax gibt automatisch einen Return Value aus, allerdings ist das für forEach nicht erforderlich.

Viele Entwickler ziehen forEach der traditionellen for-Schleife vor. Im Allgemeinen empfiehlt es sich, die Loop-Syntax zu verwenden, die Ihren Code klar, präzise und verständlich gestaltet.

4. map

Während forEach einfach einen Loop über jedes Element "zieht", lässt sich das mithilfe der map-Funktion auf Arrays ausweiten - und Aktionen auf jedes einzelne Element anwenden. Angenommen, Sie wollen in unserem Beispiel-Array jedes Element mit 10 multiplizieren, würde das wie folgt aussehen:

let modifiedArr = arr.map((x) => { return x * 10 } )

// modifiedArray now holds: [50, 100, 150, 200]

Sie haben auch die Möglichkeit, hierbei die Kurzform zu verwenden:

let modifiedArr = arr.map(x => x * 100 )

// modifiedArray now holds: [500, 1000, 1500, 2000]

Allerdings können Sie mit der längeren Form eine beliebige Logik innerhalb des Callbacks ausführen:

let modifiedArr = arr.map((x) => {

let foo = 1000;

// Do more stuff

return x * foo;

})

Je aufwändiger die Callbacks ausfallen, desto mehr nimmt die Simplizität von map ab. Im Klartext: Bevorzugen Sie wann immer möglich simple Callbacks.

5. reduce

Wann immer Sie eine JavaScript-Operation mit einem Array durchführen müssen, die dieses auf einen singulären Value "reduziert", empfiehlt sich dafür reduce als funktionaler Bestandteil von JavaScript:

const numbers = [1, 2, 3, 4];

const sum = numbers.reduce((accumulator, number) => accumulator + number);

console.log(sum); // Output: 10

Beim ersten Argument handelt es sich um den Akkumulator. Diese Variable bleibt über alle Iterationen hinweg bestehen und wird schließlich zum Output des reduce-Calls. Das zweite Argument (number) ist der Wert des Elements für die Iteration.

Sie können reduce außerdem nutzen, um eine Starting-Value anzugeben. Dazu setzen Sie ein zweites Argument nach der Callback-Funktion:

// With initial value of 10

const sum2 = numbers.reduce((accumulator, number) => accumulator + number, 10);

console.log(sum2); // Output: 20 (10 + 1 + 2 + 3 + 4)

Das kann auch hilfreich sein, wenn es sich um eine "leere" Collection handelt. In diesem Fall dient das zweite Argument als Standard-Value.

6. substring

Mit der Methode String.substring können Sie einen Teil des Strings abrufen:

// Let's get the substring of this Emerson quote:

let myString = "Enthusiasm is the mother of effort, and without it nothing great was ever achieved."

console.log(myString.substring(0,34));

// outputs: 'Enthusiasm is the mother of effort'

7. switch

Das switch-Feature kommt ins Spiel, wenn es darum geht, den Branching Control Flow zu händeln - ermöglicht Entwicklern also, Verzweigungen kompakter und verständlicher zu gestalten als etwa mit if/else. Das ist insbesondere dann hilfreich, wenn es viele Optionen gibt. Im Laufe der Jahre hat sich das switch-Statement in JavaScript zunehmend zu einem mächtigen Werkzeug weiterentwickelt. Die grundlegende Syntax sieht folgendermaßen aus:

switch (word) {

case "Enthusiasm":

console.log("This word is about passion and excitement.");

break;

case "mother":

console.log("This word is about the source or origin.");

break;

case "effort":

console.log("This word is about hard work and dedication.");

break;

default:

console.log("I don't have specific analysis for this word.");

}

Das Keyword switch akzeptiert eine Variable - in diesem Fall word. Jedes case-Statement entspricht dabei einem möglichen Wert der switch-Variable. Zu beachten ist dabei, dass ein case-Block mit dem break-Statement beendet wird. Das ist auch der wesentliche Unterschied zu Konstrukten, die geschweifte Klammern verwenden, um den Anwendungsbereich zu definieren. Wird ein break-Statement weggelassen, wird der Code dem nächsten case-Statement zugeordnet.

Im Folgenden verwenden wir das switch-Statement mit unserem Emerson-Zitat:

let myString = "Enthusiasm is the mother of effort, and without it nothing great was ever achieved."

function analyzeWord(word) {

switch (word) {

case "Enthusiasm":

console.log("This word is about passion and excitement.");

break;

case "mother":

console.log("This word is about the source or origin.");

break;

case "effort":

console.log("This word is about hard work and dedication.");

break;

default:

console.log("I don't have specific analysis for this word.");

}

}

myString.split(" ").forEach((word) => analyzeWord(word));

Dieses Beispiel kombiniert mehrere Elemente: Wir teilen den string mit Hilfe von split(" ") in substrings auf, durchlaufen dann jedes Wort mit forEach und übergeben dieses an unser switch-Statement (das in einer Funktion verpackt ist). Wenn Sie diesen Code ausführen, wird für jedes bekannte Wort eine Beschreibung und der Standardwert für alle anderen ausgegeben. (fm)

Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Infoworld.