Woraus besteht JavaScript?

Während der ersten Jahre mit JavaScript fühlte ich mich wie ein Betrüger. Obwohl ich Websites mit Frameworks erstellen konnte, hatte ich das Gefühl, dass mir etwas fehlte. JavaScript-Interviews haben mich zur Angst angeregt, weil ich die Grundlagen dieser Sprache nicht genau verstanden habe.



Im Laufe der Jahre habe ich ein mentales JavaScript-Modell entwickelt, das mir ein Gefühl des Vertrauens vermittelt. Hier möchte ich Ihnen eine sehr übersichtliche Version dieses Modells vorstellen. Die Struktur ähnelt einem Wörterbuch. Jedes Konzept wird in mehreren Sätzen beschrieben.

Versuchen Sie beim Lesen dieses Materials im Kopf einzuschätzen, wie sicher Sie sich in Bezug auf die einzelnen hier behandelten Themen fühlen. Und wenn sich herausstellt, dass Ihnen viele Dinge von hier aus nicht besonders bekannt vorkommen, werde ich Sie nicht dafür verantwortlich machen. Aber wenn dies zutrifft, gibt es am Ende des Materials etwas, das Ihnen hilft, die Situation zu korrigieren.

JavaScript-Mentalmodell


  • Wert. Der Begriff der Bedeutung ist etwas abstrakt. Es ist "etwas". Ein Wert in JavaScript entspricht einer Zahl in Mathematik oder einem Punkt in der Geometrie. Wenn Ihr Programm ausgeführt wird, ist die Welt dieses Programms voller Bedeutungen. Zahlen wie 1 , 2 und 420 sind Werte. Bedeutungen sind aber andere Wesenheiten. Zum Beispiel der Satz "Cows go moo" . Es stimmt, nicht alles hat Bedeutung. Eine Zahl ist ein Wert, aber eine if ist kein Wert mehr. Im Folgenden werden wir über verschiedene Arten von Werten sprechen.

    • Art des Wertes. Es gibt verschiedene Arten von Werten. Zum Beispiel Zahlen - wie 420 , Zeichenfolgen - wie "Cows go moo" , Objekte. Es gibt andere Arten von Werten. Sie können den typeof mit dem Operator typeof . Beispielsweise gibt der Befehl console.log(typeof 2) eine number an die Konsole aus.
    • Primitive Werte. Einige Werte haben "primitive" Typen. Dies sind Zahlen, Zeichenfolgen und einige andere Bedeutungen. Eine interessante Eigenschaft von Grundwerten ist, dass Sie nicht mehr solche Werte erstellen können, als in der Sprache vorhanden sind, und dass Sie vorhandene Grundwerte nicht ändern können. Jedes Mal, wenn Sie beispielsweise die Nummer 2 im Code verwenden, wird derselbe Wert 2 . Es ist unmöglich, einen weiteren Wert 2 im Programm zu "erstellen" oder 2 in 3 "umzuwandeln". Dies gilt auch für Streicher.
    • Die Werte sind null und undefined . Dies sind zwei spezielle Bedeutungen. Sie sind nicht wie andere, weil mit ihnen vieles nicht machbar ist - ihr Auftreten führt oft zu Fehlern. Normalerweise bedeutet die Verwendung von null , dass einer Variablen absichtlich kein Wert zugewiesen wurde, und undefined , dass ein Wert zufällig fehlt. Der Programmierer entscheidet jedoch, wie diese Werte genau verwendet werden sollen. Diese Werte existieren aufgrund der Tatsache, dass es manchmal besser ist, dass ein Fehler während der Ausführung einer bestimmten Operation aufgetreten ist, und dass die Programmausführung nach der "Verarbeitung" eines nicht vorhandenen Werts nicht fortgesetzt wird.
  • Gleichheit Der Begriff der Gleichheit ist wie der Begriff der Bedeutung einer der Grundbegriffe von JavaScript. Wir sagen, dass zwei Werte gleich sind, wenn sie ... in der Tat werde ich das nicht sagen. Wenn zwei Werte gleich sind, bedeutet dies, dass sie ein und derselbe Wert sind. Nicht zwei verschiedene Bedeutungen, sondern eine! Zum Beispiel sind die Gleichungen "Cows go moo" === "Cows go moo" und 2 === 2 wahr. Und hier ist alles klar: 2 ist 2 . Bitte beachten Sie, dass wir drei Gleichheitszeichen verwenden, die das obige Konzept der Wertegleichheit in JavaScript darstellen.

    • Strikte Gleichheit. Wir haben gerade im vorigen Absatz über ihn gesprochen.
    • Gleichheit der Links. Und wir haben auch nur über ihn gesprochen.
    • Ungleiche Gleichheit. Oh, aber das ist etwas völlig anderes. In JavaScript wird die Überprüfung auf nicht strenge Gleichheit der Werte mit einem Operator durchgeführt, der aus zwei Gleichheitszeichen ( == ) besteht. Entitäten können lose gleich erkannt werden, auch wenn sie durch unterschiedliche Bedeutungen dargestellt werden, die einander ähnlich sind (so etwas wie 2 und "2" ). Ein nicht-strenger Gleichheitsoperator wurde zu Beginn der Sprachentwicklung zur Vereinfachung in JavaScript eingefügt. Seitdem ist es eine bodenlose Quelle der Verwirrung. Das Konzept der losen Gleichheit kann nicht als grundlegend bezeichnet werden, ist jedoch eine typische Fehlerquelle. Sie können den nicht strengen Gleichheitsoperator an einem regnerischen Tag lernen, aber viele versuchen einfach, den Operator == nicht zu verwenden.
  • Wörtlich. Literale werden verwendet, wenn ein Wert referenziert wird, indem er in den Programmcode geschrieben wird. Zum Beispiel ist 2 ein numerisches Literal und "Banana" ist ein String-Literal.
  • Variabel. Mit Variablen können Sie Werte anhand von Namen referenzieren. let message = "Cows go moo" Sie zum Beispiel let message = "Cows go moo" . Nachdem im Code eine ähnliche Konstruktion verwendet wurde, können Sie, wo immer Sie den Satz "Cows go moo" benötigen, nur eine message schreiben, anstatt diesen Satz zu wiederholen. Später können Sie die message ändern message indem Sie die Variable auf etwas anderes verweisen lassen. Beispiel: message = "I am the walrus" . Bitte beachten Sie, dass dies die Bedeutung selbst nicht ändert. Dies wirkt sich nur auf das aus, worauf sich die Variable bezieht. Es ist, als würde man einen Variablennamen mit etwas anderem verbinden. Anfangs war die Variable mit „ "Cows go moo" und jetzt mit "I am the walrus" „verbunden "I am the walrus" .

    • Der Umfang der Variablen. Wenn nur eine Variable mit der message im gesamten Programm verwendet werden könnte, wäre dies sehr schlecht. Wenn wir eine Variable deklarieren, ist sie nur in einem Teil des Programms verfügbar. Dieser Teil wird als "Gültigkeitsbereich der Variablen" bezeichnet. Es gibt Regeln, die die Merkmale des Bereichs beschreiben. Sie können den Gültigkeitsbereich einer Variablen in der Regel identifizieren, indem Sie herausfinden, in welchem ​​von geschweiften Klammern ( {} ) begrenzten Block sie deklariert ist. Dieser Block kann auch als Gültigkeitsbereich der Variablen bezeichnet werden.
    • Variablen Werte zuweisen. Wenn wir im Code message = "I am the walrus" schreiben, führt dies dazu, dass wir die message so ändern, dass sie auf den Wert "I am the walrus" verweist. Diese Operation wird als Zuweisen einer Variablen zu einem Wert oder Schreiben einer Variablen oder Festlegen einer Variablen bezeichnet.
    • Die Schlüsselwörter let , const und var . In der Regel ist let das beste Schlüsselwort zum Deklarieren von Variablen. Wenn Sie sicherstellen möchten, dass nichts Neues in eine Variable geschrieben werden kann, können Sie das Schlüsselwort const . (Einige Codebasen und Befehle sind umständlich in Bezug auf dieses Problem. Wenn der Wert nur einmal in die Variable geschrieben wird, müssen Sie const .) Versuchen Sie, das Schlüsselwort var nicht zu verwenden, da mit Variablen, die mit ihr deklariert wurden, verwandte Regeln zur Definition des Gültigkeitsbereichs von Variablen.
  • Typ Object . Der Object , dessen Entitäten als Objekte bezeichnet werden, spielt in JavaScript eine besondere Rolle. Eine bemerkenswerte Eigenschaft von Objekten ist, dass sie anderen Werten zugeordnet werden können. Das {flavor: "vanilla"} -Objekt hat beispielsweise eine flavor Eigenschaft, die auf den Wert von "vanilla" verweist. Objekte können als unabhängige Werte wahrgenommen werden, von denen Verknüpfungen zu anderen Werten abgeleitet werden.

    • Eigentum des Objekts. Eine Eigenschaft ist so etwas wie eine „Verbindung“, die von einem Objekt stammt und einen bestimmten Wert angibt. Dies könnte Sie an die Idee einer Variablen erinnern: Eine Eigenschaft hat einen Namen (wie flavor ), sie zeigt auf einen Wert (wie "vanilla" ). Im Gegensatz zu einer Variablen „leben“ Eigenschaften jedoch im Objekt selbst und nicht irgendwo im Code (in einem bestimmten Bereich der Variablen). Eine Eigenschaft wird als Teil des Objekts betrachtet, und der Wert, auf den die Eigenschaft verweist, wird nicht als Teil des Objekts betrachtet.
    • Objektliteral. Ein Objektliteral ist ein Mechanismus, mit dem Sie Objekte erstellen können, indem Sie entsprechende Konstruktionen in den Code einfügen. Zum Beispiel ist dies {} oder {flavor: "vanilla"} . In geschweiften Klammern können viele durch Kommas getrennte Paare der Formulareigenschaft : werden. Auf diese Weise können wir die Werte angeben, auf die sich die Eigenschaften der Objekte beziehen.
    • Die Identität der Objekte. Wir haben bereits gesagt, dass 2 gleich 2 (mit anderen Worten - 2 === 2 ), da wir an 2 === 2 , an der wir die Zahl 2 schreiben, den gleichen Wert "nennen". Aber jedes Mal, wenn wir {} schreiben, erhalten wir unterschiedliche Werte. Infolgedessen ist ein Objekt der Form {} nicht mit einem anderen Objekt identisch, was ebenfalls wie {} aussieht. Schreiben Sie Folgendes in die Konsole: {} === {} (das Ergebnis ist false ). Wenn ein Computer auf die Nummer 2 im Code stößt, funktioniert er immer mit derselben Zwei. Aber Objektliterale sind etwas anderes. Wenn der Computer auf {} stößt, wird ein neues Objekt erstellt. Dies ist immer der neue Wert. Wie prüfe ich Objekte auf Gleichheit? Das Konzept der "Gleichheit" kann als das Konzept der "Identität von Werten" betrachtet werden. Wenn wir sagen: " a und b identisch", bedeutet dies, dass a und b denselben Wert angeben ( a === b ). Wenn wir sagen, dass a und b nicht identisch sind, bedeutet dies, dass a und b unterschiedliche Werte angeben (dh a !== b ).
    • Punktnotation. Wenn Sie den Wert einer Eigenschaft eines Objekts lesen oder etwas in eine Eigenschaft schreiben müssen, können Sie die Punktnotation ( . ) Verwenden. Wenn die Variable iceCream auf ein Objekt verweist, dessen Eigenschaft flavor die Zeichenfolge "chocolate" , gibt das Konstrukt iceCream.flavor den iceCream.flavor "chocolate" .
    • Bracket-Notation. Manchmal ist der Name der Eigenschaft des zu adressierenden Objekts nicht im Voraus bekannt. Beispielsweise müssen Sie manchmal den Wert der Eigenschaft iceCream.flavor und manchmal den Wert der Eigenschaft iceCream.flavor lesen. Mit der Klammernotation ( [] ) können Sie auf die Eigenschaften von Objekten zugreifen, indem Sie deren Namen mithilfe von Variablen festlegen. Angenommen, der Code enthält eine solche Variable: let ourProperty = 'flavor' . Dies bedeutet, dass ein Design wie iceCream[ourProperty] uns den Wert "chocolate" . Interessanterweise können Sie beim Erstellen von Objekten die Notation in Klammern verwenden: { [ourProperty]: "vanilla" } .
    • Mutation. Wir sprechen über die Tatsache, dass ein Objekt mutiert (oder sich ändert), wenn jemand einen neuen Wert in seine Eigenschaft schreibt. Wenn wir beispielsweise ein Objekt let iceCream = {flavor: "vanilla"} , können wir der Eigenschaft später mit iceCream.flavor = "chocolate" einen neuen Wert zuweisen. Bitte beachten Sie, dass selbst wenn wir die Variable iceCream mit dem Schlüsselwort const deklarieren, dies uns nicht daran hindern würde, die Eigenschaft des Objekts iceCream.flavor . Dies liegt daran, dass die Verwendung von const nur die iceCream Variable vor dem Überschreiben schützt und wir die flavor Eigenschaft des Objekts ändern, auf das die Variable verweist. Einige Leute haben sich geweigert, const nur zu verwenden, weil dieses Schlüsselwort den Programmierer irreführen kann.
    • Array Ein Array ist ein Objekt, das eine Sammlung bestimmter Werte ist. Arrays können mit Array-Literalen wie folgt deklariert werden: ["banana", "chocolate", "vanilla"] . Die Verwendung einer solchen Konstruktion führt zur Erstellung eines Objekts, dessen Eigenschaft mit dem Namen 0 auf die Zeichenfolge "banana" , Eigenschaft 1 - auf die Zeichenfolge "chocolate" , Eigenschaft 2 - auf den Wert "vanilla" verweist. Es wäre mühsam, dasselbe zu schreiben: {0: ..., 1: ..., 2: ...} . Daher sind Arrays nützliche Strukturen. Arrays verfügen über integrierte Mechanismen, die darauf ausgelegt sind, mit ihren Elementen zu arbeiten. Darunter befinden sich die map , filter und reduce . Lassen Sie sich nicht entmutigen, wenn Ihnen die Namensreduzierung verwirrend vorkommt. Es scheint für alle unverständlich.
    • Prototyp. Was passiert, wenn Sie versuchen, auf ein Objekt zuzugreifen, das nicht existiert? Was passiert zum Beispiel, wenn wir auf iceCream.taste zugreifen und das Objekt nur die Eigenschaft flavor ? Wenn wir diese Frage beantworten, ohne auf Details einzugehen, können wir sagen, dass wir einen speziellen Wert von undefined , wenn wir versuchen, eine nicht vorhandene Eigenschaft zu verwenden. Wenn Sie diese Frage ausführlich beantworten, müssen Sie damit beginnen, dass die meisten Objekte in JavaScript den sogenannten "Prototyp" haben. Der Prototyp eines Objekts kann als "versteckte" Eigenschaft wahrgenommen werden, die dem System mitteilt, wo nach der angeforderten Eigenschaft gesucht werden soll, wenn sie sich nicht im Objekt selbst befindet. Wenn sich in unserem Beispiel herausstellt, dass das iceCream Objekt iceCream Eigenschaft hat, sucht JavaScript im Prototyp des Objekts, das auch ein Objekt ist, nach dieser Eigenschaft. Und wenn er es dort nicht findet, dann im Prototyp des Prototyps und so weiter. Ein undefined Wert wird nur .taste wenn das Ende der Prototypkette erreicht ist und die Eigenschaft .taste nicht gefunden wird. Sie müssen selten direkt mit diesem Mechanismus arbeiten, aber wenn Sie die Prototypen kennen, können Sie verstehen, warum das iceCream Objekt eine toString Methode hat, die wir nie deklariert haben. Diese Methode stammt aus dem Prototyp des Objekts.
  • Funktion. Eine Funktion ist eine spezielle Bedeutung, die nur zum Darstellen eines Programmcodes existiert. Funktionen sind praktisch in Situationen, in denen der Programmierer nicht ständig den gleichen Code schreiben möchte. Ein "Aufruf" einer Funktion, die aussieht wie sayHi() teilt dem Computer mit, dass er Code innerhalb der Funktion ausführen und dann zu dem sayHi() zurückkehren muss, an dem die Funktion aufgerufen wurde. JavaScript bietet viele Möglichkeiten, Funktionen zu deklarieren, die sich geringfügig unterscheiden.

    • Argumente (oder Parameter) der Funktion. Mit Argumenten können Sie bestimmte Daten von der Stelle, an der die Funktion aufgerufen wird, an die Funktion übergeben. Zum Beispiel könnte es so aussehen: sayHi("Amelie") . Das Verhalten von Argumenten in einer Funktion ähnelt dem Verhalten von Variablen. Die Wörter "Parameter" und "Argumente" werden verwendet, je nachdem, was genau besprochen wird - über die Deklaration einer Funktion oder über ihren Aufruf. Obwohl der Unterschied in der Terminologie richtig ist - in der Praxis werden diese Begriffe synonym verwendet.
    • Funktionsausdruck. Zuvor haben wir Zeichenfolgenwerte in Variablen geschrieben. Beispiel: let message = "I am the walrus" . Wie sich herausstellt, kann eine Funktion auch in eine Variable geschrieben werden: let sayHi = function() { } . Was nach dem = -Zeichen kommt, heißt funktionaler Ausdruck. Es gibt uns eine spezielle Bedeutung (Funktion), die ein Stück Code ist. Wenn wir diesen Code ausführen müssen, können wir die entsprechende Funktion aufrufen.
    • Funktionsdeklaration. Ein Programmierer kann es leid sein, ständig so etwas wie let sayHi = function() { } schreiben. In diesem Fall kann hier eine kürzere Form zur Beschreibung einer Funktion verwendet werden: function sayHi() { } . Dieses Konstrukt heißt Funktionsdeklaration. Anstatt einen Variablennamen auf der linken Seite des Ausdrucks anzugeben, setzen wir diesen Namen nach dem function . Normalerweise sind die beiden oben beschriebenen Stile zum Erstellen von Funktionen austauschbar.
    • Funktionen an die Spitze des Bereichs heben. Normalerweise kann eine Variable nur verwendet werden, nachdem sie mit let oder const unter dem Ort ihrer Deklaration deklariert wurde. Bei Funktionen kann dies unpraktisch sein. Funktionen können sich gegenseitig aufrufen. Herauszufinden, welches zuerst erstellt werden sollte, kann eine entmutigende Aufgabe sein. Das Gute ist, dass bei Verwendung von Funktionsdeklarationen (und nur bei Verwendung dieses Ansatzes!) Die Reihenfolge, in der Funktionen beschrieben werden, nicht wichtig ist. Tatsache ist, dass bei diesem Ansatz die Funktionen in den oberen Bereich des Geltungsbereichs "aufsteigen". Das heißt, es stellt sich heraus, dass die Funktionen bereits definiert und funktionsbereit sind, selbst wenn Sie versuchen, sie aus dem Code aufzurufen, der vor ihrer Deklaration steht.
    • Dieses Schlüsselwort. Vielleicht ist das Schlüsselwort this ein JavaScript-Konzept, das am häufigsten missverstanden wird. Dieses Schlüsselwort kann mit einem speziellen Funktionsargument verglichen werden. Aber wir selbst übertragen ihre Funktionen nicht. JavaScript übergibt es. Der Wert this hängt davon ab, wie die Funktion aufgerufen wird. Wenn Sie beispielsweise eine Objektmethode mit Punktnotation wie iceCream.eat() , gibt this an, was sich vor dem Punkt befindet. In unserem Beispiel ist dies ein iceCream Objekt. Der Wert in einer Funktion hängt davon ab, wie die Funktion aufgerufen wird und nicht davon, wo sie deklariert wurde. Es gibt spezielle Methoden wie .bind , .call und .apply , die dem Programmierer die Möglichkeit geben, zu steuern, was in this .apply .
    • Pfeilfunktionen. Pfeilfunktionen ähneln funktionalen Ausdrücken. Sie werden folgendermaßen deklariert: let sayHi = () => { } . Sie sind kompakt und werden häufig für einzeilige Designs verwendet. Die Fähigkeiten von Pfeilfunktionen sind eingeschränkter als die Fähigkeiten herkömmlicher Funktionen. Zum Beispiel haben sie das Schlüsselwort this . Wenn das Schlüsselwort this in einer Pfeilfunktion verwendet wird, wird es von der Funktion übernommen, in die die Pfeilfunktion eingebettet ist. Dies ähnelt dem Aufrufen eines Arguments oder einer Variablen aus einer Funktion, die in einer anderen Funktion verschachtelt ist. In der Praxis bedeutet dies, dass Pfeilfunktionen verwendet werden, wenn derselbe Wert, der im sie umgebenden Code vorhanden ist, in ihnen sichtbar sein soll.
    • Binden this Werts an Funktionen. Normalerweise bedeutet das Binden einer bestimmten Funktion f an einen bestimmten Wert und an einen bestimmten Satz von Argumenten, dass eine neue Funktion erstellt wird, die die Funktion f mit diesen vordefinierten Werten aufruft. JavaScript verfügt über einen Hilfsmechanismus zum Binden von Funktionen - die .bind Methode, die Sie jedoch auch auf andere Weise an Funktionen binden können. Das Binden war eine beliebte Methode, um verschachtelte Funktionen zu veranlassen, denselben Wert wie externe Funktionen zu „sehen“. Jetzt werden Pfeilfunktionen in einer ähnlichen Situation verwendet, was dazu führt, dass die Funktionsbindung in unserer Zeit selten verwendet wird.
    • Stack aufrufen Das Aufrufen einer Funktion ist wie das Betreten eines Raums. Jedes Mal, wenn wir eine Funktion aufrufen, werden die darin enthaltenen Variablen erneut initialisiert. Folglich ist jeder Funktionsaufruf so etwas wie das Erstellen eines neuen "Raums" mit einem Funktionscode. Wenn der "Raum" "gebaut" ist, er "eingegeben" ist, wird der Funktionscode ausgeführt. Variablen, die in einer Funktion "live" in diesem "Raum" deklariert sind. Wenn die Rückkehr von der Funktion ausgeführt wird, verschwindet der „Raum“ mit seinem gesamten Inhalt. Alle diese durch Funktionsaufrufe erzeugten "Räume" können als hoher "Turm" dargestellt werden. Dies ist eine Aufrufliste. Wenn wir eine bestimmte Funktion verlassen, gelangen wir zu der Funktion, die sich im Aufrufstapel "darunter" befindet.
    • Rekursion. Rekursion ist, wenn eine Funktion sich selbst aufruft. Diese Technik ist in Fällen nützlich, in denen das, was bereits von der Funktion ausgeführt wurde, wiederholt werden muss, jedoch andere Argumente verwendet werden. Wenn wir beispielsweise eine Suchmaschine schreiben, die Websites durchsucht, verfügen wir möglicherweise über die Funktion collectLinks(url) . Diese Funktion sammelt zuerst Links auf einer Seite einer Site und ruft sich dann selbst auf, wobei alle gefundenen Links an sich selbst übergeben werden. , . , , , . , , stack overflow . - , .
    • . — , , . , , — . — , — , , . , .
    • . () — , JavaScript. , , . : . . , setTimeout , … -. , . — . « », , .
    • . , , , , . - , . ? - . — . . , - . JavaScript, , . «». JavaScript, , , , .

Zusammenfassung


JavaScript , . . JavaScript. , . JavaScript. — Just JavaScript . , , JavaScript.

Sehr geehrte Leser! JavaScript?

Source: https://habr.com/ru/post/de482472/


All Articles