JavaScript Verständnissfrage - Quellcode

Peter P.

Cadet 3rd Year
Registriert
Mai 2017
Beiträge
32
Halli hallo hallöchen,

aktuell arbeite ich mit dem Buch Node.ja, Das Praxis Buch, Sebastian Springer, Rheinwerk Verlag, 2., akutallisierte und erweiterte Auflage aus Seite 100 habe ich folgenden Quelltext entnommen.

Code:
var ignore = /[\.,]/g;
var seperator = " ";
var wordSCount = function (sentence) {
    var wordCount = {};
    var words = sentence.replace(ignore, '').toLowerCase().split(seperator);

    for (var i in words){
        wordCount[words[i]] = wordCount[words[i]] +1 || 1;
    }
    return wordCount;
};
exports.wordSCount = wordSCount;

Der Quelltext soll einen Satz entgegennehmen, dabei die Punkte und Kommas entfernen und zählen wie häufig das selbe Wort im Satz enthalten ist. Danei wird die wird die Abzahl der Wörter in einer Objektstruktur gespeichert.

Der Quelltext ist lauffähig und liefert auch das gwünschte Ergebnis. Konkret bezieht sich meine Frage auf den Inhalt der for-Schleife (Zeile 8), was passiert ist nachvollziehbar, die Syntax dazu ist mir jedoch unverständlich.
Freundliche Grüße

Peter P.
 
words enthält durch die RegExp ein Array aus Wörtern, alle lowercase.

Die for-Schleife ist hier eigentlich eine foreach Schleife, also:
Für jedes Element mit Index i im Array words tue:
Und dann wird das Wort für das Array benutzt (hab vergessen, wie das heißt :D)

Also wenn das Wort "hallo" ist, steht da wordCount[hallo]
Wenn wordCount[xy] nicht initialisiert ist, wird es auf 1 gesetzt ( " || 1") sonst wird 1 hinzu addiert.

Lg, Franz
 
Peter P. schrieb:
Der Quelltext ist lauffähig und liefert auch das gwünschte Ergebnis. Konkret bezieht sich meine Frage auf den Inhalt der for-Schleife (Zeile 8), was passiert ist nachvollziehbar, die Syntax dazu ist mir jedoch unverständlich.
Man könnte es auch länger schreiben (das || durch if ersetzt):
Code:
    for (var i in words){
        if ( wordCount[words[i]] + 1 ) 
        {
            wordCount[words[i]] = wordCount[words[i]] + 1
        } 
        else
        {
            wordCount[words[i]] = 1
        } 
    }

Grundlage für die sehr kurze Schreibweise ist, das Javascript bei logischen Operatoren null- und undefined- Werte als "false" behandelt. (siehe auch dem Link von Yuuri oder die diesbezügliche Dokumentation bei Mozilla)
 
Zuletzt bearbeitet:
Hallo Community,

vielen Dank für die schnellen und freundlichen Antworten.

Es ist nicht der ||-Opterator welcher mich iritiert. Für mich ist unklar warum die Syntax;

Code:
var person = {
};

person['name'] =  1;

Den Schlüssel "Name" mit dem Wert 1 im Objektliterial anlegt.

@Anderas stimmt dies?

Code:
if ( wordCount[words[i]] + 1 )

oder sollte es

Code:
if ( wordCount[words[i]])

heißen? oder ist er in diesem Falle egal welche der Beiden Varianten?

Freundliche Grüße

PP
 
Peter P. schrieb:
Es ist nicht der ||-Opterator welcher mich iritiert. Für mich ist unklar warum die Syntax;
Den Schlüssel "Name" mit dem Wert 1 im Objektliterial anlegt.
Das ist aber in jeder Sprache so. Ein Objekt ist ja intern nichts weiter als ein Dictionary, wo Wertepaare hinterlegt werden. Wie du darauf zugreifst, ist syntaktischer Zucker. Ob das nun also objekt[key] oder objekt.key oder was auch immer ist, ist für das Interne ja irrelevant.

Du kannst in JS auch über Objekte iterieren (siehe Zeile 7). Angewandt auf dein person-Objekt, würdest du bei Zeile 7 in i den Wert "name" haben und könntest über person[i] auf den Wert 1 gelangen. Analog für weitere Keys, die du darin speicherst.
Peter P. schrieb:
oder ist er in diesem Falle egal welche der Beiden Varianten?
Ist egal. Alles was nicht gesetzt wurde, ist in JavaScript undefined. undefined + 1 evaluiert zu NaN, ist also immer noch false. Durch || 1 setzt du nun hierbei den Standardwert bzw. initialisierst damit.

Deine Schleife oben mal explizit ausgeschrieben.
Code:
for( var i in words )
{
	var wort = words[i];
	if( undefined === typeof wordCount[wort] ) // undefined == bisher nicht gesetzt
	{
		wordCount[wort] = 1;
	}
	wordCount[wort] = wordCount[wort] + 1;
}
Die Prüfung hab ich hier mal so aufgeschrieben, wie sie eigentlich sein sollte. Beachte aber die Bemerkung oben mit
Code:
undefined + 1 === NaN == false
.
 
Zuletzt bearbeitet:
Peter P. schrieb:
Es ist nicht der ||-Opterator welcher mich iritiert. Für mich ist unklar warum die Syntax;

Code:
var person = {
};

person['name'] =  1;

Den Schlüssel "Name" mit dem Wert 1 im Objektliterial anlegt.
Dann solltest Du Dich mit assoziativen Javascript-Arrays beschäftigen.

Ansonsten habe ich das mit dem +1 absichtlich so geschrieben, da ich denselben Wert prüfen wollte, der im Original mit || benutzt wird. Wenn Du die von mir verlinkte Doku gelesen hättest, dann wäre Dir klar gewesen, dass null-Werte, NaN-Werte, 0, "" und undefined-Werte allesamt als false interpretiert werden. Warum das deshalb auch mit +1 funktioniert hat Yuuri schon geschrieben.
 
Zuletzt bearbeitet: (Typo)
Das in der Schleife ist eines der Dinge warum so viele JavaScript hassen. In jeder anderen Programmiersprache würdest du in der Schleife das Objekt bekommen, in JavaScript bekommst du aber nur den Index des Objektes. Darum ergibt sich dieses Geschwurbel in Zeile 8. Deswegen ruft man [words] auf, um an das Objekt mit dem gewünschten Inhalt zu kommen.

Die Zuweisung lässt sich auch anders schreiben, vielleicht wird es dann klarer:
Code:
var person = {"name": 1, "nachname":2, ...}

Die Besonderheit ist, dass du innerhalb der geschweiften Klammern keine Variablen nutzen kannst. Das geht erst mit neuen JS Versionen indem man die Variablen in eckige Klammern setzt.

Code:
// geht nicht
var text = "abc";
var person = {text: 123}

// geht
var text = "abc";
var person[text] = 123;

// geht in neuen JS versionen
var text = "abc";
var person = {[text]: 123}

// entspricht
var person = {"abc": 123}
 
Zuletzt bearbeitet:
Zurück
Oben