JavaScript wird gemäß dem ECMAScript-Standard entworfen und implementiert. Die später erwähnte JavaScript-Syntax ist tatsächlich die Implementierung des ES5-Standards.
Was sind zunächst einmal die grundlegenden Grammatiken?
Was sind die grundlegendsten Grammatiken?
Die grundlegende Syntax fast aller Sprachen unterscheidet sich kaum, es gibt nichts weiter als Datentypen, Operatoren, Steueranweisungen, Funktionen usw., hier ist eine kurze Liste.
5 grundlegende Datentypen und 1 komplexer Datentyp
JavaScript enthält 5 grundlegende Datentypen. Die Daten Typen sind undefiniert / null / boolean / number / string Dies sind die fünf grundlegenden Datentypen, es gibt keine anderen!
JavaScript enthält einen komplexen Datentyp, nämlich den Objekttyp. Der Objekttyp ist die Basisklasse aller anderen Objekte.
Hinweis: JavaScript unterscheidet nicht zwischen Gleitkommazahlen und Ganzzahlen, sie werden alle durch Zahlen dargestellt.
Die 5 zuvor erwähnten grundlegenden Datentypen und der 1 komplexe Datentyp hier, das sind alle Datentypen!
Grundlegende Operatoren
Das ist gesunder Menschenverstand, man muss nur wissen, was los ist.
Zu den häufig verwendeten Operatoren gehören: arithmetische Operatoren, relationale Operatoren, boolesche Operatoren, Zuweisungsoperatoren usw.
Kontrollanweisung
Das nennen wir oft if-else und andere Kontrollanweisungen.
Es gibt nicht viele häufig verwendete: if-Anweisung, switch-Anweisung, for-Anweisung, while-Anweisung, for-in-Anweisung.
Funktion
Eine Funktion ist eine Kapselung eines kleinen Teils der Logik. Theoretisch gilt: Je unabhängiger die Logik, desto besser.
JavaScript-Funktionen unterscheiden sich stark von anderen Sprachen. JavaScript-Funktionen können sowohl Parameter als auch Rückgabewerte annehmen.
Darüber hinaus können JavaScript-Funktionen eine beliebige Anzahl von Parametern akzeptieren, und auf diese Parameter kann über das Argumentobjekt zugegriffen werden.
Die grundlegende Syntax jeder Sprache ist die gleiche, bis auf einige Unterschiede im Detail, sie ist ungefähr die oben genannte: Datentypen, Operatoren, Steueranweisungen, Funktionen, Module usw.
Im Folgenden werden einige etwas komplexere Konzepte vorgestellt.
Variablen, Umfang, Speicherprobleme
Variablen
JavaScript-Variablen werden in zwei Typen unterteilt : Grundtypen und Referenztypen. Die Grundtypen sind die fünf zuvor erwähnten Basisdatentypen, und die Referenztypen sind das zuvor erwähnte Objekt und andere darauf basierende komplexe Datentypen.
✦ Grundtyp: belegt die tatsächliche Größe des Speichers. Beim Zuweisen eines Werts wird eine neue Kopie im Speicher erstellt. Im Stapelspeicher gespeichert.
✦ Referenztyp: ein Zeiger auf ein Objekt und nicht auf das Objekt selbst. Beim Zuweisen eines Werts wird einfach ein neuer Zeiger erstellt, der auf das Objekt zeigt. Im Heap-Speicher gespeichert.
Variable Speicherzuordnung
Kurz gesagt ist der Basistyp der tatsächliche Wert im Speicher, während der Referenztyp ein Zeiger im Speicher ist. Wenn Sie auf ein Objekt verweisen, können mehrere Referenztypen gleichzeitig auf dasselbe Objekt verweisen.
Wie kann man also bestimmen, um welchen Datentyp es sich bei einer bestimmten Variablen handelt?
Um zu bestimmen, um welchen Grundtyp es sich bei einer Variablen handelt, verwenden Sie den Operator „typeof“.
Um zu bestimmen, um welchen Referenztyp es sich bei einer Variablen handelt, verwenden Sie den Operator „instanceof“.
Vergiss das nicht!
Bereich
Variablen werden in einem bestimmten Bereich deklariert, und der Bereich bestimmt die Lebensdauer von Variablen und was Code kann auf die darin enthaltenen Variablen zugreifen.
Der JavaScript-Bereich umfasst nur den globalen Bereich und den Funktionsbereich und nicht den Bereich auf Blockebene!
Bereiche können verschachtelt werden, um eine Bereichskette zu bilden. Aufgrund der Existenz der Bereichskette kann die Suche nach Variablen nach oben verfolgt werden, dh die untergeordnete Funktion kann auf den Bereich der übergeordneten Funktion => auf den Bereich der Vorfahrenfunktion => bis zum globalen Bereich zugreifen Die Funktion wird auch als Abschluss bezeichnet und später vorgestellt.
var color = "blue"; function changeColor() { var anotherColor = "red"; function swapColors() { var tempColor = anotherColor;
color = tempColor; / Auf Farbe, anotherColor, tempColor kann hier zugegriffen werden
} // Auf Farbe, anotherColor kann hier zugegriffen werden, auf tempColor
kann jedoch nicht zugegriffen werden swapColors();
}// Nur Farbe, changeColor();
Umfangskette
Das Konzept des Umfangs scheint einfach, aber bei der tatsächlichen Verwendung gibt es viele Probleme. Wenn Sie auf Probleme stoßen, müssen Sie diese sorgfältig analysieren.
Speicherprobleme
Die JavaScript-Engine verfügt über einen automatischen Garbage-Collection-Mechanismus und erfordert nicht allzu viel Aufmerksamkeit zu Speicherzuweisungs- und Garbage-Collection-Problemen. Ich werde hier nicht weiter darauf eingehen!
Referenztyp
Wie bereits erwähnt, ist Object der einzige komplexe Datentyp, von dem Referenztypen abgeleitet werden Der Objekttyp wird vererbt.
✦ Array: Array-Typ
✦ Datum: Datumstyp
✦ RegExp: Regulärer Ausdruckstyp. Es hat Vorteile, mehr darüber zu erfahren!
✦ Moment...
Die Frage ist, welcher Datentyp ist die am häufigsten verwendete Funktion? Die Antwort ist Funktionstyp!
Hey, ich habe anscheinend etwas entdeckt? Da Function ein Referenztyp ist, kann JavaScript Eigenschaften und Methoden zu Referenztypen hinzufügen. Nun, das können Funktionen auch! Hier werden JavaScript-Funktionen leistungsstark und komplex. Das heißt: Funktionen können auch benutzerdefinierte Methoden und Eigenschaften haben!
Darüber hinaus kapselt JavaScript auch drei der fünf oben genannten Grundtypen mit Referenztypen, nämlich Boolean, Number und String. Sie werden jedoch nicht häufig verwendet, sodass Sie sie nur verstehen müssen.
Bevor der gesamte Code ausgeführt wird, sind übrigens zwei Objekte in den Bereich integriert, nämlich Global und Math. Das Global des Browsers ist window!
Bisher sind die Grundkonzepte in JavaScript relativ komplex, während andere relativ einfach sind.
Als nächstes werde ich einige etwas komplexere Konzepte in JavaScript vorstellen: objektorientiert.
Objektorientierte Programmierung
JavaScript selbst verfügt nicht über die Konzepte von Klassen und Schnittstellen basiert auf realisierten Prototypen.
Der Einfachheit halber analysieren wir nur zwei objektorientierte Probleme:
✦ Wie definiere ich eine Klasse?
✦ So implementieren Sie die Klassenvererbung
Definieren Sie eine Klasse
Ich werde es Ihnen direkt sagen, ohne über etwas anderes zu sprechen. Wir verwenden Konstruktor + Prototyp, um eine Klasse zu definieren.
Verwenden Sie den Konstruktor, um einen benutzerdefinierten Typ zu erstellen, und verwenden Sie dann den neuen Operator, um eine Instanz der Klasse zu erstellen. Die Methoden und Eigenschaften des Konstruktors sind jedoch in jedem Beispiel vorhanden und können nicht gemeinsam genutzt werden, daher führen wir sie ein Prototypen zur Implementierung der gemeinsamen Nutzung von Methoden und Eigenschaften.
Prototyp
Schließlich definieren wir die Methoden und Eigenschaften, die auf dem Prototyp geteilt werden müssen, und fügen die für die Instanz spezifischen Methoden und Eigenschaften ein der Konstrukteur. Zu diesem Zeitpunkt haben wir eine Klasse über Konstruktor + Prototyp definiert.
//Konstruktorfunktion Person(name, age, job) { this.name = name; this.age = age this.friends = ["Shelby", "Court"];
}// Prototype Person.prototype = {
Konstruktor: Person,
sayName: function() { return this.name;
}
}// Instanziiere var person1 = neue Person ("Nicholas", 29, "Software Engineer");var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
warning (person1.friends); falsealert(person1.sayName === person2.sayName); //Ausgabe true
Vererbung implementieren
Im vorherigen Artikel ging es darum, wie man eine Klasse definiert. Anschließend definieren wir eine übergeordnete Klasse und eine Unterklasse.
Wie erbt eine Unterklasse von einer übergeordneten Klasse? Ohne weitere Umschweife sage ich es Ihnen direkt. JavaScript implementiert die Vererbung über die Prototypenkette!
Wie baut man eine Prototypenkette auf? Weisen Sie einfach die übergeordnete Klasseninstanz dem Prototyp des untergeordneten Klassenkonstruktors zu. Es ist verwirrend, aber Sie müssen es sich merken!
Vererbung der Prototypkette
Nach dem Aufbau der Prototypkette kann die Unterklasse auf alle Eigenschaften und Methoden der übergeordneten Klasse zugreifen Klasse !
// Übergeordnete Klassenfunktion SuperType() { this.property = true;
}
SuperType.prototype.getSuperValue = function() { return this.property;
};// Unterklassenfunktion SubType() { this.subproperty = false;
}//Die Unterklasse erbt die übergeordnete Klasse SubType.prototype = new SuperType();//Fügt der Unterklasse eine neue Methode hinzu SubType.prototype.getSubValue = function( ) { return this.subproperty;
};//Überschreiben Sie die Methode der übergeordneten Klasse SubType.prototype.getSuperValue = function() { return false;
};//Instanziieren Sie die var-Instanz = new SubType();console . log(instance.getSuperValue()); //Ausgabe false
Objektorientiertes Wissen kann in ein Buch geschrieben werden. Hier ist nur eine kurze Einführung in die grundlegendsten und am häufigsten verwendeten Konzepte.
Funktionsausdruck
Es gibt zwei Möglichkeiten, Funktionen in JavaScript zu definieren: Funktionsdeklaration und Funktionsausdruck.
Durch die Verwendung von Funktionsausdrücken entfällt die Notwendigkeit, die Funktion zu benennen, wodurch eine dynamische Programmierung, also anonyme Funktionen, erreicht wird. Mit anonymen Funktionen haben JavaScript-Funktionen leistungsfähigere Einsatzmöglichkeiten.
Rekursion
Rekursion ist ein sehr verbreiteter Algorithmus, das klassische Beispiel ist faktoriell. Ohne über irgendetwas anderes zu sprechen, sprechen Sie einfach über die beste Praxis der Rekursion:
// Beste Praxis, Funktionsausdruck var factial = (function f(num) { if (num <= 1) { return 1;
} else { return num * f(num - 1);
}
});// Nachteile: // Fakultät kann geändert werden // was zu return num * factial( num - 1) Fehlerfunktion Factorial(num) { if (num <= 1) { return 1;
} else { return num * Faculty(num - 1);
}
}// Nachteile: // arguments.callee, die Spezifikation hat die Verwendung der Funktion factial(num) { if (num <= 1) { return 1;
} else { return num * arguments.callee(num - 1); }
Rekursion ist immer noch die Methode arguments.callee. Dies ist die beste Vorgehensweise.
Nun, viele Leute denken, dass Rekursion schwierig zu schreiben ist. Tatsächlich wird es viel klarer, wenn man es in zwei Schritte unterteilt.
✦ Randbedingungen, normalerweise if-else.✦ Rekursiver Aufruf.
Folgen Sie diesem Modus, üben Sie mit ein paar klassischen Rekursionen und Sie werden sich mit ihnen vertraut machen.
Verschluss
Viele Leute denken oft, dass Verschlüsse kompliziert sind und leicht ins Wanken geraten, aber das ist nicht der Fall.
Was ist also eine Schließung? Wenn eine Funktion auf Variablen im Gültigkeitsbereich einer anderen Funktion zugreifen kann, handelt es sich bei ersterer um einen Abschluss. Da JavaScript-Funktionen natürlich Funktionen zurückgeben können, besteht eine gängige Methode zum Erstellen von Abschlüssen darin, eine weitere Funktion innerhalb einer Funktion zu erstellen!
Daran ist nichts Magisches. Durch die Definition einer untergeordneten Funktion in einer übergeordneten Funktion wird ein Abschluss erstellt, und die untergeordnete Funktion kann auf den Bereich der übergeordneten Funktion zugreifen.Wir haben normalerweise Angst vor Abschlüssen, weil wir uns von ihnen täuschen lassen, insbesondere wenn es in Vorstellungsgesprächen viele Abschlüsse gibt.
Die Definition des Abschlusses wurde bereits erwähnt, und wie man einen Abschluss erstellt, wurde auch erwähnt. Sprechen wir also über die Mängel des Abschlusses und wie man sie löst.
/* Wir geben das Funktionsarray über subFuncs zurück und rufen dann die Ausführung separat auf */// Geben das Array von subFuncs der Funktion zurück, und diese Funktionen haben Verweise auf die Variablen von superFunc // Dies ist ein typischer Abschluss / / Was ist also das Problem Wollstoff? // Wenn wir zurückgehen und die Funktion in subFuncs ausführen, ist das i, das wir erhalten, eigentlich immer 10. Warum? // Denn wenn wir subFuncs zurückgeben, ist i=10 in superFunc // Wenn also die Funktion in subFuncs ausgeführt wird, ist die Ausgabe i 10. // // Das Obige ist die größte Gefahr bei Schließungen. Um es in einem Satz zu verstehen: // Der Verweis der Unterfunktion auf die übergeordnete Funktionsvariable ist der Zustand der Variablen, nachdem die übergeordnete Funktion die Ausführung der Funktion superFunc() beendet hat. { var subFuncs = new Array( ); for (var i = 0; i < 10; i++) {
subFuncs[i] = function() { return i;
};
} return subFuncs ;
}// Also, wie kann man die Schließungsgrube der Berufung lösen? // Tatsächlich ist das Prinzip sehr einfach, da die Essenz der Abschlussgrube darin besteht, dass die Referenz der untergeordneten Funktion auf die Variable der übergeordneten Funktion der Zustand der Variablen ist, nachdem die Ausführung der übergeordneten Funktion abgeschlossen ist. // Dann lösen wir die Methode Dieses Problem ist: Die untergeordnete Funktion verweist auf die übergeordnete Funktion. Variablenreferenz, Laufzeitstatus verwenden // Wie mache ich das? //Fügen Sie auf der Grundlage des Funktionsausdrucks einfach die Selbstausführung hinzu. function superFunc() { var subFuncs = new Array(); for (var i = 0; i < 10; i++) {
subFuncs[i] = function(num) { return function() { return num;
};
(i);
Aufgrund der Besonderheit von JavaScript-Funktionen können wir Funktionen zurückgeben. Wenn wir eine Funktion als Abschluss zurückgeben, ist die von der Funktion referenzierte übergeordnete Funktionsvariable der Status nach Abschluss der Ausführung der übergeordneten Funktion, nicht der Status zur Laufzeit. Das ist die größte Gefahr bei Schließungen. Um diese Falle zu lösen, besteht unser üblicher Weg darin, Funktionsausdrücke selbst ausführen zu lassen.
Da sich Schließungen außerdem auf den Umfang der Vorfahrenfunktionen beziehen, kommt es beim Missbrauch von Schließungen zu Speicherproblemen.
Es geht hauptsächlich um Kapselung...
Kapselung
Abschlüsse können private Variablen oder Bereiche auf Blockebene kapseln.
➙ Kapselung des Bereichs auf BlockebeneJavaScript verfügt nicht über das Konzept des Bereichs auf Blockebene, sondern nur auf den globalen Bereich und den Funktionsbereich. Wenn wir also einen Bereich auf Blockebene erstellen möchten, können wir ihn durch Schließung simulieren.
Das Erstellen und sofortige Aufrufen einer Funktion kapselt einen Bereich auf Blockebene. Diese Funktion kann den darin enthaltenen Code sofort ausführen und die internen Variablen werden sofort nach der Ausführung zerstört.
function outputNumbers(count) { // Verwenden Sie im Funktionsbereich den Abschluss, um den Bereich auf Blockebene zu kapseln
// In diesem Fall ist i nicht extern verfügbar und es wird einen ähnlichen Block geben -level Scope
(function() { for (var i = 0; i < count; i++) {
warning(i);
})();
Warnung (i); //Verursachen Sie einen Fehler! }//Verwenden Sie im globalen Bereich Abschlüsse, um den Bereich auf Blockebene zu kapseln.//Auf diese Weise wird der Codeblock den globalen Bereich nicht verschmutzen (Funktion() { var now = new Date(); if (now.getMonth() == 0 && now.getDate() == 1) {
warning("Frohes neues Jahr!");
}
})() ;// Ja, der Kern der Kapselung des Bereichs auf Blockebene ist Folgendes: Funktionsausdruck + Selbstausführung! (function() { //Dies ist der Bereich auf Blockebene})();
➙ Kapselung privater Variablen
JavaScript hat kein Konzept privater Variablen, wir können auch Abschlüsse verwenden Um dies zu erreichen, kapseln öffentliche Methoden private Variablen, indem sie Variablen ausblenden und Methoden offenlegen.
(function() { //Private Variablen und private Funktionen
} } //Konstruktor
MyObject = function() {}; //Öffentliche/privilegierte Methoden
privateVariable++; return privateFunction();
};
})();
Was können Sie abschließend sagen?
Dies ist fast eine grundlegende Syntax und eine etwas fortgeschrittenere Verwendung von JavaScript. Tatsächlich sind die sogenannten Fortgeschrittenen Manifestationen der „Unausgereiftheit“ von JavaScript, insbesondere objektorientiert, für technische Anforderungen, aber JavaScript selbst ist keine perfekte Unterstützung. Glücklicherweise hat der neueste ES6-Standard viele Probleme gelöst, und Sie müssen sich bei der Verwendung mit Babel keine allzu großen Sorgen um die Kompatibilität machen. Wenn Sie ein Anfänger sind, empfehle ich Ihnen, direkt zu ES6+Babel zu wechseln.
✦ Die Grundlage von JavaScript umfasst hauptsächlich: 5 grundlegende Datentypen, 1 komplexer Datentyp, Operatoren, Steueranweisungen, Funktionen usw.
✦ Nachdem Sie die grundlegende Syntax verstanden haben, müssen Sie auch JavaScript-Variablen, -Bereiche und -Bereichsketten lernen.
✦ Gängige Referenztypen können gleichzeitig überprüft und verwendet werden. Als jemand, der es erlebt hat, empfehle ich Ihnen, mehr Regeln zu lernen, was Ihre Programmierfähigkeiten erheblich verbessern wird.
✦ Es gibt viele Möglichkeiten, objektorientierte Programmierung durchzuführen. Sie müssen nur daran denken, Konstruktor + Prototyp zum Definieren einer Klasse zu verwenden und die Prototypenkette zum Implementieren der Vererbung zu verwenden. Weitere Erweiterungen finden Sie im Buch.
✦ Funktionsausdrücke führen zu mehreren interessanten Dingen: Rekursion, Schließung und Kapselung. Denken Sie an die Best Practices der Rekursion, die Definition und die Fallstricke des Abschlusses sowie die anwendbaren Abschlussszenarien.
Als dynamische Sprache unterscheidet sich JavaScript deutlich von anderen Sprachen, was es für viele Menschen auch schwierig macht, JavaScript zu lernen. Aber wenn Sie sich jetzt den vorherigen Artikel ansehen, handelt es sich zwar um eine kurze Zusammenfassung, dies ist jedoch der Hauptinhalt von JavaScript, also haben Sie keine Angst vor sich selbst.
Noch etwas: Wenn Sie ein Neuling sind, empfehle ich Ihnen, direkt zu ES6+Babel zu wechseln.
Weitere JavaScript-Wissenspunkte und verwandte Artikel finden Sie auf der chinesischen PHP-Website!