Das Material, dessen Übersetzung wir heute veröffentlichen, ist den Grundlagen von JavaScript gewidmet und richtet sich an Programmierer für Anfänger. Es kann als kleiner Hinweis auf die Grundkonstruktionen von JS betrachtet werden. Hier werden wir insbesondere über das Datentypsystem, über Variablen, über Arrays, über Funktionen, über Prototypen von Objekten und über einige andere Merkmale der Sprache sprechen.

Primitive Datentypen
Die folgenden primitiven Datentypen sind in JavaScript verfügbar:
number
,
boolean
,
string
,
undefined
,
null
. Es sollte sofort beachtet werden, dass wir bei der Arbeit mit primitiven Datentypen, beispielsweise mit Zeichenfolgenliteralen, auch ohne explizite Konvertierung auf deren Methoden und Eigenschaften zugreifen können. Der Punkt hier ist, dass beim Versuch, solche Operationen auszuführen, Literale automatisch mit dem entsprechenden Objekt-Wrapper ausgestattet werden.
▍ Zahlen
JavaScript hat nur einen Zifferntyp - Gleitkommazahlen mit doppelter Genauigkeit. Dies führt dazu, dass die Ergebnisse der Berechnung einiger Ausdrücke arithmetisch falsch sind. Möglicherweise wissen Sie bereits, dass in JS der Wert des Ausdrucks
0.1 + 0.2
nicht
0.3
. Gleichzeitig werden beim Arbeiten mit ganzen Zahlen solche Probleme nicht beobachtet,
1 + 2 === 3
.
JavaScript verfügt über ein
Number
Objekt, bei dem es sich um einen Objekt-Wrapper für numerische Werte handelt. Objekte vom Typ
Number
können entweder mit einem Befehl der Form
var a = new Number(10)
werden oder Sie können sich auf das automatische Verhalten des oben beschriebenen Systems verlassen. Auf diese Weise können Sie insbesondere in
Number.prototype
gespeicherte Methoden
Number.prototype
, die auf numerische Literale angewendet werden:
(123).toString(); //"123" (1.23).toFixed(1); //"1.2"
Es gibt globale Funktionen, mit denen Werte anderer Typen in einen numerischen Typ konvertiert werden können. Dies sind
parseInt()
,
parseFloat()
und das
Number()
parseFloat()
, das in diesem Fall als normale Funktion fungiert, die die Typkonvertierung durchführt:
parseInt("1") //1 parseInt("text") //NaN parseFloat("1.234") //1.234 Number("1") //1 Number("1.234") //1.234
Wenn während der Operation mit Zahlen etwas erhalten wird, das keine Zahl ist (während einiger Berechnungen oder beim Versuch, etwas in eine Zahl umzuwandeln), gibt JavaScript keinen Fehler aus, sondern zeigt das Ergebnis einer solchen Operation als den Wert
NaN
(Not-a-Number, keine Zahl). Um zu überprüfen, ob ein bestimmter Wert
NaN
, können Sie die Funktion
isNaN()
verwenden.
JS-Arithmetikoperationen funktionieren auf eine recht vertraute Weise, aber Sie müssen darauf achten, dass der Operator
+
das Hinzufügen von Zahlen und das Verketten von Zeichenfolgen durchführen kann.
1 + 1 //2 "1" + "1" //"11" 1 + "1" //"11"
▍Strings
JavaScript-Zeichenfolgen sind Unicode-Zeichenfolgen. String-Literale werden erstellt, indem der Text in doppelte (
""
) oder einfache (
''
) Anführungszeichen eingeschlossen wird. Wie bereits erwähnt, können wir uns bei der Arbeit mit String-Literalen auf den entsprechenden Objekt-Wrapper verlassen, dessen Prototyp viele nützliche Methoden enthält, darunter
indexOf()
,
concat()
,
concat()
.
"text".substring(1,3) //ex "text".indexOf('x') //2 "text".concat(" end") //text end
Strings sind wie andere primitive Werte unveränderlich. Beispielsweise
concat()
die
concat()
-Methode keine vorhandene Zeichenfolge, sondern erstellt eine neue.
▍Logische Werte
Der logische Datentyp in JS wird durch zwei Werte dargestellt -
true
und
false
. Die Sprache kann verschiedene Werte automatisch in einen logischen Datentyp konvertieren. Falsch sind also zusätzlich zum logischen Wert
false
die Werte
null
,
undefined
,
''
(leere Zeichenfolge),
0
und
NaN
. Alles andere, einschließlich aller Objekte, repräsentiert wahre Bedeutungen. Im Verlauf logischer Operationen wird alles, was als wahr angesehen wird, in
true
, und alles, was als falsch angesehen wird, wird in falsch umgewandelt. Schauen Sie sich das folgende Beispiel an. In Übereinstimmung mit den obigen Prinzipien wird eine leere Zeichenfolge in
false
konvertiert
false
und als Ergebnis dieser Codeausführung wird die Zeichenfolge
This is false
an die Konsole gesendet.
let text = ''; if(text) { console.log("This is true"); } else { console.log("This is false"); }
Die Objekte
Objekte sind dynamische Strukturen, die aus Schlüssel-Wert-Paaren bestehen. Werte können primitive Datentypen haben, können Objekte oder Funktionen sein.
Objekte lassen sich am einfachsten mit der Objektliteral-Syntax erstellen:
let obj = { message : "A message", doSomething : function() {} }
Die Eigenschaften eines Objekts können jederzeit gelesen, hinzugefügt, bearbeitet und gelöscht werden. So geht's:
object.name, object[expression]
: object.name, object[expression]
.- Schreiben von Daten in Eigenschaften (wenn die Eigenschaft, auf die zugegriffen wird, nicht vorhanden ist, wird eine neue Eigenschaft mit dem angegebenen Schlüssel hinzugefügt):
object.name = value
, object[expression] = value
. - Eigenschaften entfernen:
delete object.name
delete object[expression]
.
Hier einige Beispiele:
let obj = {}; // obj.message = "A message"; // obj.message = "A new message"; // delete object.message; //
Objekte in der Sprache werden als Hash-Tabellen implementiert. Eine einfache Hash-Tabelle kann mit dem
Object.create(null)
:
let french = Object.create(null); french["yes"] = "oui"; french["no"] = "non"; french["yes"];//"oui"
Wenn das Objekt unveränderlich gemacht werden muss, können Sie den Befehl
Object.freeze()
.
Um alle Eigenschaften eines Objekts zu
Object.keys()
, können Sie den Befehl
Object.keys()
:
function logProperty(name){ console.log(name); // console.log(obj[name]); // } Object.keys(obj).forEach(logProperty);
▍Vergleich von Werten primitiver Typen und Objekte
In der praktischen Arbeit mit primitiven Werten können Sie sie, wie bereits erwähnt, als Objekte mit Eigenschaften und Methoden wahrnehmen, obwohl sie keine Objekte sind. Primitive Werte sind unveränderlich, die interne Struktur von Objekten kann sich ändern.
Variablen
In JavaScript können Variablen mit den Schlüsselwörtern
var
,
let
und
const
deklariert werden.
Mit dem Schlüsselwort
var
können Sie eine Variable deklarieren und bei Bedarf mit einem bestimmten Wert initialisieren. Wenn die Variable nicht initialisiert ist, ist ihr Wert
undefined
. Mit dem Schlüsselwort
var
deklarierte Variablen haben einen Funktionsumfang.
Das Schlüsselwort
let
ist
var
sehr ähnlich. Der Unterschied besteht darin, dass Variablen, die mit dem Schlüsselwort
let
deklariert wurden, einen Blockbereich haben.
Mit dem Schlüsselwort
const
deklarierte Variablen haben auch einen Blockbereich, der angesichts der Tatsache, dass die Werte solcher Variablen nicht geändert werden können, korrekter als "Konstanten" bezeichnet wird. Das Schlüsselwort
const
, das den Wert einer mit ihm deklarierten Variablen "einfriert", kann mit der
Object.freeze()
-Methode verglichen werden, die Objekte "einfriert".
Wenn eine Variable außerhalb einer Funktion deklariert wird, ist ihr Gültigkeitsbereich global.
Arrays
Arrays in JavaScript werden mithilfe von Objekten implementiert. Wenn wir über Arrays sprechen, diskutieren wir daher Objekte, die Arrays ähnlich sind. Sie können mit Array-Elementen anhand ihrer Indizes arbeiten. Numerische Indizes werden in Zeichenfolgen konvertiert und als Namen für den Zugriff auf die Werte von Array-Elementen verwendet. Beispielsweise ähnelt ein Konstrukt der Form
arr[1]
einem Konstrukt der Form
arr['1']
, und beide geben Zugriff auf denselben Wert:
arr[1] === arr['1']
. In Übereinstimmung mit dem Obigen wird ein einfaches Array, das durch den Befehl
let arr = ['A', 'B', 'C']
deklariert wurde, als ein Objekt der folgenden Form dargestellt:
{ '0': 'A', '1': 'B', '2': 'C' }
Das Entfernen von Array-Elementen mit dem Befehl
delete
hinterlässt Lücken. Um dieses Problem zu vermeiden, können Sie den Befehl
splice()
, der jedoch langsam funktioniert, da nach dem Löschen eines Elements die verbleibenden Elemente des Arrays verschoben und tatsächlich an den Anfang des Arrays nach links verschoben werden.
let arr = ['A', 'B', 'C']; delete arr[1]; console.log(arr); // ['A', empty, 'C'] console.log(arr.length); // 3
Array-Methoden erleichtern die Implementierung von Datenstrukturen wie Stapeln und Warteschlangen:
// let stack = []; stack.push(1); // [1] stack.push(2); // [1, 2] let last = stack.pop(); // [1] console.log(last); // 2 // let queue = []; queue.push(1); // [1] queue.push(2); // [1, 2] let first = queue.shift();//[2] console.log(first); // 1
Funktionen
Funktionen in JavaScript sind Objekte. Funktionen können Variablen zugewiesen, in Objekten oder Arrays gespeichert, als Argumente an andere Funktionen übergeben und von anderen Funktionen zurückgegeben werden.
Es gibt drei Möglichkeiten, Funktionen zu deklarieren:
- Klassische Funktionsdeklaration (Funktionsdeklaration oder Funktionsanweisung).
- Die Verwendung von Funktionsausdrücken (Funktionsausdruck), die auch als Funktionsliterale (Funktionsliteral) bezeichnet werden.
- Verwendung der Syntax von Pfeilfunktionen (Pfeilfunktion).
▍ Klassische Funktionsdeklaration
Bei diesem Ansatz zum Deklarieren von Funktionen gelten die folgenden Regeln:
- Das erste Schlüsselwort in einer Funktionsdeklarationszeile ist
function
. - Funktionen müssen einen Namen erhalten.
- Die Funktion kann im Code vor ihrer Deklaration verwendet werden, da die Deklaration der Funktion an die Spitze des Bereichs angehoben wird, in dem sie deklariert ist.
So sieht eine klassische Funktionsdeklaration aus:
function doSomething(){}
▍ Funktionsausdrücke
Bei der Verwendung von Funktionsausdrücken sollte Folgendes berücksichtigt werden:
- Das
function
ist nicht mehr das erste Wort in einer Funktionsdeklarationszeile. - Ein Funktionsname ist optional. Es können sowohl anonyme als auch benannte Funktionsausdrücke verwendet werden.
- Befehle zum Aufrufen solcher Funktionen sollten den Befehlen für ihre Deklaration folgen.
- Eine solche Funktion kann unmittelbar nach der Deklaration mit der Syntax von IIFE (Sofort aufgerufener Funktionsausdruck - sofort als Funktionsausdruck bezeichnet) gestartet werden.
Der funktionale Ausdruck sieht folgendermaßen aus:
let doSomething = function() {}
▍ Pfeilfunktionen
Pfeilfunktionen können in der Tat als „syntaktischer Zucker“ betrachtet werden, um anonyme funktionale Ausdrücke zu erstellen. Es ist zu beachten, dass solche Funktionen keine eigenen Entitäten und
arguments
. Die Pfeilfunktionsdeklaration sieht folgendermaßen aus:
let doSomething = () = > {};
▍ Möglichkeiten zum Aufrufen von Funktionen
Funktionen können auf verschiedene Arten aufgerufen werden.
Normaler Funktionsaufruf
doSomething(arguments)
Funktionsaufruf in Form einer Objektmethode
theObject.doSomething(arguments) theObject["doSomething"](arguments)
Konstruktorfunktionsaufruf
new doSomething(arguments)
Aufrufen einer Funktion mit der Methode apply ()
doSomething.apply(theObject, [arguments]) doSomething.call(theObject, arguments)
Aufrufen einer Funktion mit der Methode bind ()
let doSomethingWithObject = doSomething.bind(theObject); doSomethingWithObject();
Funktionen können mit mehr oder weniger Argumenten als der Anzahl der Parameter aufgerufen werden, die bei der Deklaration angegeben wurden. Während der Arbeit der Funktion werden die "zusätzlichen" Argumente einfach ignoriert (obwohl die Funktion Zugriff darauf hat), die fehlenden Parameter erhalten den Wert
undefined
.
Funktionen haben zwei Pseudoparameter:
this
und
arguments
.
▍ Stichwort dies
Das
this
repräsentiert den Kontext einer Funktion. Der Wert, auf den es zeigt, hängt davon ab, wie die Funktion aufgerufen wurde. Hier sind die Bedeutungen
this
Schlüsselworts in Abhängigkeit davon, wie die Funktion aufgerufen wird (sie werden oben mit Codebeispielen beschrieben, deren Konstruktionen hier verwendet werden):
- Der übliche Funktionsaufruf ist
window
/ undefined
. - Ein Funktionsaufruf in Form einer Objektmethode ist
theObject
. - Ein Funktionsaufruf in Form eines Konstruktors ist ein neues Objekt.
- Aufrufen einer Funktion mit der Methode
apply()
- theObject
. - Aufrufen einer Funktion mit der Methode
bind()
- theObject
.
▍ Schlüsselwortargumente
Das
arguments
Schlüsselwort ist ein Pseudoparameter, der Zugriff auf alle Argumente gibt, die zum Aufrufen der Funktion verwendet werden. Es sieht aus wie ein Array, aber kein Array. Insbesondere verfügt es nicht über Array-Methoden.
function reduceToSum(total, value){ return total + value; } function sum(){ let args = Array.prototype.slice.call(arguments); return args.reduce(reduceToSum, 0); } sum(1,2,3);
Eine Alternative zum
arguments
Schlüsselwort ist die neue Syntax für die verbleibenden Parameter. Im folgenden Beispiel ist
args
ein Array, das alles enthält, was beim Aufruf an die Funktion übergeben wurde.
function sum(...args){ return args.reduce(reduceToSum, 0); }
▍Operator zurück
Eine Funktion ohne
return
gibt
undefined
. Achten Sie mit dem Schlüsselwort
return
darauf, wie der automatische Einfügungsmechanismus für Semikolons funktioniert. Die folgende Funktion gibt beispielsweise kein leeres Objekt, sondern einen
undefined
Wert zurück:
function getObject(){ return { } } getObject()
Um ein ähnliches Problem zu vermeiden, muss die öffnende geschweifte Klammer in derselben Zeile wie die
return
:
function getObject(){ return { } }
Dynamische Eingabe
JavaScript ist eine dynamische Schreibsprache. Dies bedeutet, dass bestimmte Werte Typen haben, Variablen jedoch nicht. Während der Programmausführung können Werte unterschiedlichen Typs in dieselbe Variable geschrieben werden. Hier ist ein Beispiel für eine Funktion, die mit Werten verschiedener Typen arbeitet:
function log(value){ console.log(value); } log(1); log("text"); log({message : "text"});
Um den in einer Variablen gespeicherten Datentyp herauszufinden, können Sie den Operator
typeof()
:
let n = 1; typeof(n); //number let s = "text"; typeof(s); //string let fn = function() {}; typeof(fn); //function
Single-Threaded-Ausführungsmodell
Die JavaScript-Laufzeit ist Single-Threaded. Dies drückt sich insbesondere in der Unmöglichkeit aus, zwei Funktionen gleichzeitig auszuführen (wenn Sie die Möglichkeiten der asynchronen Codeausführung, die wir hier nicht ansprechen, nicht berücksichtigen). Die Laufzeit hat eine sogenannte Ereigniswarteschlange, in der eine Liste der Aufgaben gespeichert ist, die verarbeitet werden müssen. Infolgedessen ist für ein JS-Ausführungsschema mit einem Thread das Problem der gegenseitigen Ressourcensperren nicht typisch, weshalb der Sperrmechanismus hier nicht benötigt wird. Code, der in die Ereigniswarteschlange fällt, muss jedoch schnell ausgeführt werden. Wenn Sie mit viel Arbeit überladen, reagiert die Anwendungsseite in der Browseranwendung, dem Hauptthread, nicht auf Benutzeraktionen, und der Browser bietet an, diese Seite zu schließen.
Ausnahmebehandlung
JavaScript verfügt über einen Mechanismus zur Behandlung von Ausnahmen. Es funktioniert nach einem für solche Mechanismen üblichen Prinzip: Der Code, der einen Fehler verursachen kann, wird mit dem
try/catch
Konstrukt ausgeführt. Der Code selbst befindet sich im
try
Block, Fehler werden im
catch
.
Es ist interessant festzustellen, dass JavaScript im Notfall manchmal keine Fehlermeldungen erzeugt. Dies liegt an der Tatsache, dass JS bis zur Übernahme des ECMAScript 3-Standards keine Fehler ausgegeben hat.
Im folgenden Codefragment schlägt beispielsweise der Versuch fehl, ein "eingefrorenes" Objekt zu ändern, es wird jedoch keine Ausnahme ausgelöst.
let obj = Object.freeze({}); obj.message = "text";
Einige der "stillen" JS-Fehler werden im strikten Modus angezeigt. Sie können sie mithilfe der Konstruktion
"use strict";
aktivieren
"use strict";
.
Prototypsystem
Die Basis solcher JS-Mechanismen wie Konstruktorfunktionen, der Befehl
Object.create()
, das Schlüsselwort
class
, basiert auf einem Prototypsystem.
Betrachten Sie das folgende Beispiel:
let service = { doSomething : function() {} } let specializedService = Object.create(service); console.log(specializedService.__proto__ === service);
Hier wurde der Befehl
Object.create()
verwendet, um ein
specializedService
service
zu erstellen, dessen Prototyp ein
service
sollte. Als Ergebnis stellt sich heraus, dass die Methode
doSomething()
durch Zugriff auf das Objekt
doSomething()
aufgerufen werden kann. Dies bedeutet außerdem, dass die Eigenschaft
__proto__
des Objekts
specializedService
auf ein
service
verweist.
Erstellen Sie nun ein ähnliches Objekt mit dem Schlüsselwort
class
:
class Service { doSomething(){} } class SpecializedService extends Service { } let specializedService = new SpecializedService(); console.log(specializedService.__proto__ === SpecializedService.prototype);
In der
Service
Klasse deklarierte Methoden werden dem
Service.prototype
Objekt hinzugefügt. Instanzen der
Service
Klasse haben denselben Prototyp (
Service.prototype
). Alle Instanzen delegieren Methodenaufrufe an das
Service.prototype
Objekt. Infolgedessen stellt sich heraus, dass Methoden in
Service.prototype
nur einmal deklariert werden.
Service.prototype
werden sie von allen Instanzen der Klasse "geerbt".
▍ Prototypkette
Objekte können „Erben“ anderer Objekte sein. Jedes Objekt hat einen Prototyp, dessen Methoden ihm zur Verfügung stehen. Wenn Sie versuchen, auf eine Eigenschaft zuzugreifen, die sich nicht im Objekt selbst befindet, beginnt JavaScript, in der Prototypenkette danach zu suchen. Dieser Vorgang wird fortgesetzt, bis die Eigenschaft gefunden wurde oder bis die Suche das Ende der Kette erreicht.
Informationen zur funktionalen Programmierung in JavaScript
In JavaScript sind Funktionen erstklassige Objekte, die Sprache unterstützt den Schließmechanismus. Dies eröffnet den Weg zur Implementierung funktionaler Programmiertechniken in JS. Insbesondere sprechen wir über die Möglichkeit, Funktionen höherer Ordnung zu verwenden.
Ein Abschluss ist eine interne Funktion, die Zugriff auf Variablen hat, die in der übergeordneten Funktion deklariert sind, auch nachdem die übergeordnete Funktion ausgeführt wurde.
Eine Funktion höherer Ordnung ist eine Funktion, die andere Funktionen als Argumente verwenden, Funktionen zurückgeben oder beides ausführen kann.
Die funktionale Programmierung in JS wird in vielen Veröffentlichungen behandelt. Wenn Sie interessiert sind, finden Sie hier einige Materialien zu diesem Thema, die sich
mit erstklassigen Funktionen ,
Kompositionen ,
Dekoratoren ,
Verschlüssen und
Lesbarkeit von Code befassen, der in einem funktionalen Stil geschrieben wurde.
Zusammenfassung
Die Stärke von JavaScript liegt in seiner Einfachheit. Das Verständnis der grundlegenden Mechanismen der Sprache ermöglicht es dem Programmierer, der JS verwendet, diese Mechanismen effektiver anzuwenden, und legt die Grundlage für sein berufliches Wachstum.
Liebe Leser! Welche Funktionen von JavaScript verursachen Ihrer Meinung nach die meisten Neulinge?
