Teil1 handgeschriebener Code
Der handgeschriebene Code vor Ort ist heutzutage eine sehr häufige Art von Interviewfragen in Interviews, in denen grundlegende Datenstrukturen und Algorithmusfähigkeiten untersucht werden.
1. Implementierung der Array -Deduplizierung
Basisarray -Deduplizierung
Array.Prototype.unique = function () {var result = []; this.foreach (Funktion (v) {if (result.indexof (v) <0) {result.push (v);}}); Rückgabeergebnis;}• Verwenden Sie die Hash -Tabelle, um zu deduplizieren. Dies ist eine Möglichkeit, Platz für Zeit auszutauschen
Array.prototype.unique = function () {var result = [], Hash = {}; this.foreach (Funktion (v) {if (! hash [v]) {Hash [v] = true; result.push (v);}}); Rückgabeergebnis;}In der obigen Methode gibt es einen Fehler. Für Arrays [1,2, '1', '2', 3] ist das Deduplizierungsergebnis [1,2,3]. Der Grund dafür ist, dass das Objekt den Attributindex wirkt, wenn das Objekt indiziert. Arr ['1'] und arr [1] erhalten beide die Werte von arr [1], sodass einige Änderungen vorgenommen werden müssen:
Array.prototype.unique = function () {var result = [], Hash = {}; this.foreach (Funktion (v) {var type = typeof (v); // Elementtyp Hash [v] || (Hash [v] = new Array ()); if (Hash [v] .Indexof (type) <0) {Hash [v] .push (type); // Speichertyp -Ergebnis. Rückgabeergebnis;}• Sortieren Sie zuerst und entfernen Sie dann die Wiederholung
Array.Prototype.unique = function () {var result = [this [0]]; this.sort (); this.foreach (Funktion (v) {v! = result [result.Length - 1] && result.push (v); // Vergleiche nur mit dem letzten Element des Ergebniss});}2 Implementierung der schnellen Sortierung
Methode 1 (verwenden Sie die JS -Array -Methode nicht so weit wie möglich):
Funktion QuickSort (arr) {QSORT (arr, 0, arr.length - 1);} Funktion qSort (arr, niedrig, hoch) {if (niedrig <hoch) {var partey = partition (arr, niedrig, hoch); QSORT (arr, niedrig, partey - 1); QSORT (arr, partey + 1, hoch); }} Funktionpartition (arr, niedrig, hoch) {var key = arr [niedrig]; // Verwenden Sie das erste Element als Klassifizierungsbasis, während (niedrig <hoch) {while (niedrig <hoch && arr [hoch]> = arr [Schlüssel]); arr [niedrig] = arr [hoch]; while (niedrig <hoch && arr [niedrig] <= arr [Schlüssel]) niedrig ++; arr [hoch] = arr [niedrig]; } arr [niedrig] = Schlüssel; Rückkehr niedrig;}Methode 2 (mit JS -Array -Methode):
Funktion QuickSort (arr) {if (arr.length <= 1) return arr; var index = math.floor (arr.length/2); var key = arr.SPLICE (Index, 1) [0]; var links = [], rechts = []; arr.foreach (Funktion (v) {v <= Schlüssel? Return Quicksort (links) .Concat ([Schlüssel], QuickSort (rechts));}Darüber hinaus sollte beachtet werden, dass die durchschnittliche Zeitkomplexität der schnellen Sortierung O (NLOGN), der schlimmste Fall ein geordneter Fall ist, die zeitliche Komplexität quadratisch n ist und die schnelle Sortierung instabil ist.
Part2 JavaScript verwandt
1 JavaScript -grundlegende Datentypen
JavaScript -Datentypen enthalten primitive Typen und Referenztypen, und es gibt fünf primitive Typen:
Nummer (Wert) String (String) boolean (boolean) null (leer) undefiniert (undefiniert)
Es gibt einen Referenztyp:
Objekt (Objekt)
Durch TypeOF (x) können Sie die Datentypen "Nummer", "String", "boolean", "undefined" und "Objekt" einer Variablen x zurückgeben. Eine Sache, die hier zu beachten ist: Der TypeOf -Operator gibt Objekt für Null -Typen zurück.
"JavaScript Advanced Programing":
Dies ist tatsächlich ein Fehler in der ersten Implementierung von JavaScript, die später von ECMascript verwendet wurde. Null wird jetzt als Platzhalter für das Objekt angesehen und erklärt so diesen Widerspruch. Aber technisch ist es immer noch der ursprüngliche Wert.
2 Sprechen Sie über JavaScript Scope -Kette
Bei der Ausführung eines Stücks JavaScript -Code (globaler Code oder Funktion) erstellt die JavaScript -Engine einen Umfang dafür, auch als Ausführungskontext bezeichnet. Nachdem die Seite geladen wurde, wird zuerst ein globaler Umfang erstellt, und dann wird jede Funktion ausgeführt. Ein entsprechender Bereich wird festgelegt, wodurch eine Bereichskette bildet. Jedes Bereich hat eine entsprechende Bereichskette, der Kopf der Kette ist der globale Bereich, und der Schwanz der Kette ist der aktuelle Funktionsbereich.
Der Zweck der Scope -Kette ist es, Kennungen zu analysieren. Wenn die Funktion erstellt wird (nicht ausgeführt), werden diese Argumente, benannten Parameter und alle lokalen Variablen in der Funktion dem aktuellen Bereich hinzugefügt. Wenn JavaScript die Variable X ermitteln muss (dieser Prozess wird als variable Auflösung bezeichnet), wird zunächst gesucht, ob es in der Kette der Kette ein X -Attribut vom Ende der Kette gibt, dh dem aktuellen Umfang. Wenn es nicht gefunden wird, suchen Sie weiter entlang der Bereichskette, bis der Kettenkopf, dh die globale Bereichskette, und die Variable nicht gefunden wird, es wird angenommen, dass es keine X -Variable in der Umfangskette dieses Codes gibt und eine Referenzfehler (ReferenzError) ausgeworfen wird.
3 So verstehen Sie die JavaScript -Prototyp -Kette
Jedes Objekt in JavaScript hat ein Prototypattribut, das wir es als Prototyp nennen, und der Wert des Prototyps ist ebenfalls ein Objekt. Daher hat es auch einen eigenen Prototyp, der eine Prototypkette verbindet. Der Header der Prototypkette ist Objekt, und sein Prototyp ist relativ speziell mit einem Wert von NULL.
Die Funktion der Prototypkette wird für die Objektvererbung verwendet. Die Prototyp -Eigenschaft von Funktion A ist ein Objekt. Wenn diese Funktion als Konstruktor verwendet wird, um eine Instanz zu erstellen, wird die Prototyp -Eigenschaft der Funktion allen Objektinstanzen als Prototyp zugewiesen. Wenn wir beispielsweise ein neues Array erstellen, wird die Array -Methode aus dem Prototyp des Arrays vererbt.
Suchen Sie beim Zugriff auf ein Attribut eines Objekts zuerst nach dem Objekt selbst und kehren Sie zurück, wenn es gefunden wird. Wenn es nicht gefunden wird, suchen Sie weiter nach den Eigenschaften seines Prototypobjekts (falls es noch nicht gefunden wird, sucht es tatsächlich nach der Prototypkette bis zur Wurzel nach oben). Solange es nicht überschrieben ist, können die Eigenschaften des Objektprototyps in allen Fällen gefunden werden, und wenn die gesamte Prototyp -Kette nicht gefunden wird, wird sie undefiniert zurückkehren.
4 JavaScript -Variable -Deklaration im Voraus
Die maßgebliche Anleitung zu JavaScript erklärt Folgendes: JavaScript -Variablen sind vor der Deklaration verfügbar, und dieses Merkmal von JavaScript wird informell bezeichnet, dh alle Variablen, die in JavaScript -Funktionen deklariert sind (aber keine Zuweisungen), sind "fortgeschritten" zur oberen Seite der Funktion.
Aus einem Beispiel:
var scope = "global"; function myfunc () {console.log (scope); var scope = "local";}Was die Konsole ausdruckt, ist nicht "global", sondern "undefiniert". Dies liegt daran, dass im Bereich des Funktionsmyfunc die lokale variable Zielfernrohrerklärung an die Spitze der Funktion vorangetrieben wird. Zu diesem Zeitpunkt deklariert der Umfang nur Werte und weist keine Werte zu, sodass die Ausgabe undefiniert ist. Tatsächlich entspricht der obige Code dem folgenden:
var scope = "global"; Funktion myfunc () {var scope; console.log (scope); scope = "local";}5 Wie man Javascript -Schließungen versteht und anwendet
Die in der Literatur angegebenen Konzepte zur spezifischen Definition von Schließungen sind sehr abstrakt. Ich denke, Schließungen sind ein Syntaxmechanismus, der Funktionen für alle lokalen Variablen anderer Funktionen ermöglicht.
Zum Beispiel:
Funktion outfunc () {var name = "vicfeel"; Funktion Infunc () {console.log (Name); } return Infunc;} Infunc (); // Konsole zeigt "vicfeel" anWir können dieses Beispiel sehen, dass auf den lokalen Variablennamen von Outfunc im Funktionsinfunc weiterhin zugegriffen werden kann.
Beispiele für Verschlussanwendungen simuliert die privaten Eigenschaften einer Klasse. Wenn Sie die Eigenschaften der Schließung nutzen, können auf lokale Variablen nur in der Sayage -Methode zugegriffen werden, und der Name wird auch extern zugegriffen, wodurch die privaten Eigenschaften der Klasse implementiert werden.
Funktion user () {this.name = "vicfeel"; // das Gesamtattribut var age = 23; // Private Attribut this.sayage: function () {console.log ("Mein Alter ist" + Alter); }} var user = new user (); console.log (user.name); // "vicfeel" console.log (user.age); // "undefined" user.sayage (); // "Mein Alter ist 23"Um mehr über Schließungen zu erfahren, empfehle ich Ruan Yifengs Netzwerkprotokoll - Lernen Sie JavaScript Closure (Verschluss).
6 Die Essenz des neuen Bauobjekts
Funktion user () {this.name = "vicfeel"; this.age = 23;} var user = new user ();Über den neuen Bediener werden die folgenden Vorgänge tatsächlich im Konstruktorbenutzer ausgeführt:
• Erstellen Sie ein neues Objekt, dessen Typ Objekt ist.
• Setzen Sie die internen, zugänglichen und Prototypen dieses neuen Objekts wie im Konstruktor festgelegten (in Bezug auf den Konstruktor, auf den durch Prototypen hingewiesen wird.
• Konstruktor ausführen;
• Gibt das neu erstellte Objekt zurück.
Funktion user () {// this = {}; //this.constructor = user; this.name = "vicfeel"; this.age = 23; // zurückgeben; } var user = new user ();Wenn der Konstruktor standardmäßig ein neu erstelltes Objekt zurückgibt, ist es ungültig, wenn eine Variable manuell zurückgegeben wird, wenn es sich bei der Variablen vom ursprünglichen Typ befindet, und wenn es sich um ein Objekt handelt, wird es zurückgegeben.
7 JavaScript -Agent
Wenn wir vielen Elementen Ereignisse hinzufügen müssen, können wir die Verarbeitungsfunktion auslösen, indem wir Ereignisse zu ihrem übergeordneten Knoten hinzufügen und Ereignisse an den übergeordneten Knoten delegieren.
Zum Beispiel müssen wir eine UL dynamisch viele Li hinzufügen, und wir müssen LI durchqueren, um Klick -Ereignisse einzeln hinzuzufügen.
<ul id = 'list'> </ul> var count = 100; var ufllist = document.getElementById ("Liste"); // Dynamischer Konstruktionsknoten für (var i = count; i-;) {var lidom = document.createelement ('li'); Ullist.AppendChild (Lidom); } // Binding klicken Sie auf Ereignis var linode = ullist.getElementByTagName ("li"); für (var i = 0, l = linodes.length; i <l; i ++) {linode [i] .onclick = function () {// li klicke auf Ereignis}} klickenWie wir alle wissen, sind DOM-Operationen sehr leistungsstark. Die wiederholte Ereignisbindung ist also einfach ein Performance -Killer. Die Kernidee des Event -Proxy besteht darin, so viele Ereignisse wie möglich durch so wenige Bindungen wie möglich anzuhören. Wie macht ich das? Die Antwort besteht darin, den Ereignisblasenmechanismus zu verwenden, um den übergeordneten Knoten UL (Ereignisblase) zu binden und dann Ereignis zu verwenden.
var count = 100; var ufllist = document.getElementById ("Liste"); // Dynamischer Konstruktionsknoten für (var i = count; i-;) {var lidom = document.createelement ('li'); Ullist.AppendChild (Lidom); } // Binding klicken Sie auf Ereignis var linode = ullist.getElementByTagName ("li"); linode.onclick = function (e) {if (e.target && e.target.nodename.touppercase == "li") {// li klicken Sie auf Ereignis}}Neue Inhalte werden kontinuierlich aktualisiert ...