Vor kurzem hat
SmartSpate beschlossen, Fragen zu
JavaScript zu sammeln und zu beantworten. Das Material, dessen Übersetzung wir veröffentlichen, enthält etwas mehr als zwei Dutzend Fragen zu JavaScript und die Antworten darauf. Das hier behandelte Themenspektrum ist recht breit. Dies sind insbesondere Funktionen der Sprache, Probleme, auf die Programmierer beim Schreiben von JS-Code stoßen, die im Browser und in Node.js arbeiten.

Frage Nummer 1. Vererbung von Prototypen
Ich habe mich an die „klassischen“ Klassen gewöhnt, aber beschlossen, JavaScript zu lernen. Ich habe ein Problem beim Verständnis des Prototypmodells. Wenn möglich, erläutern Sie in Form von Vorlagen die Möglichkeit, „Klassen“ in JavaScript zu erstellen, und informieren Sie uns über die geschlossenen und offenen Methoden und Eigenschaften von Klassen. Ich verstehe, dass bereits viel darüber geschrieben wurde und dass in JavaScript die Methoden und Eigenschaften von Objekten standardmäßig öffentlich verfügbar sind, aber ich möchte dies alles richtig verstehen. Wie funktioniert die Vererbung von Prototypen in JavaScript?
▍ Antwort
Die klassische Vererbung erinnert sehr daran, wie Menschen die Gene ihrer Vorfahren erben. Menschen haben einige gemeinsame Grundfähigkeiten wie Gehen und Sprechen. Darüber hinaus hat jede Person einige Besonderheiten. Menschen können ihre "Klasse" nicht ändern, aber sie können ihre eigenen "Eigenschaften" innerhalb bestimmter Grenzen ändern. Gleichzeitig können Großeltern, Mütter und Väter die Gene von Kindern oder Enkelkindern im Laufe ihres Lebens nicht beeinflussen. Also ist alles auf der Erde angeordnet, aber stellen wir uns einen anderen Planeten vor, auf dem Vererbungsmechanismen auf besondere Weise funktionieren. Angenommen, einige mutationsfähige Organismen nutzen dort die Mechanismen der "telepathischen Vererbung". Dies drückt sich darin aus, dass sie im Laufe ihres Lebens die genetische Information ihrer eigenen Nachkommen verändern können.
Betrachten Sie das Beispiel der Vererbung auf diesem seltsamen Planeten. Das Vater-Objekt erbt Gene vom Großvater-Objekt und das Sohn-Objekt erbt genetische Informationen vom Vater. Jeder Bewohner dieses Planeten kann die Gene seiner Nachkommen frei mutieren und verändern. Zum Beispiel hat bei "Großvater" die Haut eine grüne Farbe. Dieses Zeichen wird vom „Vater“ und vom „Sohn“ geerbt. Plötzlich entscheidet "Großvater", dass er es satt hat, grün zu sein. Jetzt möchte er blau sein und seine Hautfarbe ändern (in Bezug auf JS - ändert den Prototyp seiner Klasse), indem er diese Mutation „telepathisch“ an den „Vater“ und den „Sohn“ weitergibt. Danach beschließt „Vater“, der glaubt, dass „Großvater“ aus dem Kopf überlebt hat, seine Gene so zu ändern, dass er wieder grün wird (dh er ändert seinen eigenen Prototyp). Diese Änderungen werden "telepathisch" an den "Sohn" übertragen. Infolgedessen haben sowohl der „Vater“ als auch der „Sohn“ wieder eine grüne Haut. Gleichzeitig ist "Großvater" immer noch blau. Egal was er mit seiner Farbe macht, es wird niemanden betreffen. Und das alles ist darauf zurückzuführen, dass der "Vater" die Farbe seiner Haut in seinem "Prototyp" explizit festgelegt hat und der "Sohn" diese Farbe erbt. Dann denkt der "Sohn" so: "Ich werde schwarz. Und lassen Sie meine Nachkommen Farbe von meinem Vater erben. “ Zu diesem Zweck ändert er sein eigenes Eigentum (und nicht das Eigentum seines Prototyps) so, dass sein Eigentum seine Farbe, aber nicht seine Nachkommen beeinflusst. Wir drücken dies alles in Form von Code aus:
var Grandfather = function () {};
Frage Nummer 2. Objekte erstellen
Wenn Sie mit dem
new
Schlüsselwort neue Instanzen von Objekten erstellen, wie können Sie sich dann vor Fehlern schützen? So arbeite ich normalerweise:
- Ich konstruiere Konstruktorfunktionen immer so, dass sie mit einem Großbuchstaben beginnen.
- Ich überprüfe die Richtigkeit der Operation mit dem Konstrukt
this instanceof Function_Name
(aus Leistungsgründen versuche ich, das Konstrukt des Typs this instanceof arguments.callee
nicht zu verwenden). - Dieser Ansatz ähnelt dem vorherigen, wird jedoch mit
window
verglichen, da ich die Namen von Entitäten nicht gerne hart codiere und keinen Code für andere Umgebungen als den Browser schreiben muss.
Was ist das bequemste Modell zum Erstellen von Objekten?
▍ Antwort
Sowohl ideologisch als auch basierend auf der Vertrautheit dieser Methode ist es am besten, Objekte mit dem
new
Schlüsselwort zu erstellen. In diesem Fall müssen den Konstruktorfunktionen Namen gegeben werden, die mit einem Großbuchstaben beginnen.
Ich halte mich lieber an die Regeln und führe keine zusätzlichen Überprüfungen der Konstruktoren durch. Wenn der Konstruktor ohne
new
aufgerufen wird und die Arbeit im globalen Bereich beginnt, kann dies mit "Selbsttäuschung" verglichen werden. Gleichzeitig empfehle ich keinesfalls, dass Sie Situationen in Designern behandeln, in denen sie ohne das
new
Schlüsselwort aufgerufen werden. Zum Beispiel könnte es so aussehen: Wenn der Konstruktor ohne
new
aufgerufen wird, wird ohnehin ein neues Objekt erstellt und zurückgegeben. Dieser Ansatz ist ideologisch falsch und führt zu Fehlern.
Hier ist ein Beispiel für die Arbeit mit einem Konstruktor.
var Obj = function () { "use strict"; this.pew = 100; };
Es ist besser, das
new
Schlüsselwort nicht für Factory-Methoden zu verwenden und in Fällen, in denen kein Konstruktor erforderlich ist, wenn es bequemer ist, ein Objekt mit einem Objektliteral zu erstellen. Angenommen, der im folgenden Beispiel gezeigte Konstruktorcode ist explizit redundant:
Wenn Sie auch zum Erstellen eines kleinen Objekts noch einen Konstruktor benötigen, ist dies besser:
var Obj = function () { "use strict"; this.pew = 100; };
Wie oben gezeigt, tritt hier ein Fehler auf, wenn der Konstruktor im strengen Modus arbeitet, wenn er ohne
new
aufgerufen wird.
Frage Nummer 3. Abfangen von Mausklicks
Wie können Sie mithilfe von JavaScript feststellen, auf welche Maustaste geklickt wird?
▍ Antwort
Durch Klicken auf die Maustasten werden
mousedown
und
mouseup
generiert. In diesem Fall wird das
click
nur mit der linken Maustaste generiert. In der Ereignisbehandlungsroutine müssen Sie den Code in der Eigenschaft
event.button
überprüfen, um herauszufinden, welche Schaltfläche gedrückt wird (0 - links, 1 - Mitte, 2 - rechts). Im IE sieht jedoch alles etwas anders aus. Betrachten Sie ein Beispiel:
var button = document.getElementById ('button'),
Die jQuery-Bibliothek berücksichtigt diese IE-Funktion. Wenn Sie sie also in einem beliebigen Browser verwenden, überprüfen Sie einfach den Wert der
event.which
Eigenschaft, anstatt mit
event.button
:
$('button').mousedown(function (event) { alert(['Left', 'Middle', 'Right'][event.which]); });
Frage Nummer 4. Abfangen von Tastenanschlägen auf Tastaturtasten
Ist es möglich, mit JavaScript die Pfeiltasten (insbesondere die Abwärts- und Aufwärts-Tasten) abzufangen, sodass der Browser nach dem Klicken nicht durch die Seite rollt? Wenn dies möglich ist, welche Funktionen bietet es dann, dies in verschiedenen Browsern zu implementieren? Angenommen, eine Seite wird auf einer Seite angezeigt, die nicht vollständig auf den Bildschirm passt. Das Bewegen durch die Zellen dieser Tabelle muss mit den Pfeiltasten organisiert werden, und es ist erforderlich, dass der Browser beim Klicken auf diese Tasten nicht durch die Seite blättert.
▍ Antwort
Um so etwas zu implementieren, müssen Sie zunächst die Standardsystemantwort auf Steueraktionen deaktivieren. Zum Beispiel scrollen die Pfeiltasten und das Mausrad durch die Seite. Wenn Sie mit der rechten Maustaste auf eine Seite klicken, wird ein Kontextmenü
form.submit()
Wenn Sie auf die Schaltfläche "
form.submit()
klicken, wird die Funktion "
form.submit()
. Wenn Sie auf das Eingabefeld klicken, wird der Eingabefokus angezeigt. Wenn Sie auf den Link klicken, wird der Browser geladen die Seite, zu der es führt.
Dies kann
auf verschiedene Arten erfolgen . Zum Beispiel so:
window.addEventListener("keydown", function(e) {
Die Seite danach reagiert normalerweise nicht auf Pfeiltasten.
Eine wichtige Sache, die hier zu beachten ist. Die Methode
preventDefault()
bevor die Standardaktion ausgeführt wird. Wenn Sie beispielsweise auf ein Feld klicken, um zu verhindern, dass es den Eingabefokus erhält, müssen Sie den entsprechenden Handler vor der Standardaktion an ein Ereignis in der Ereigniskette hängen. In unserem Fall handelt es sich um ein
mousedown
Ereignis:
$('input').bind ('mousedown', function (event) { event.preventDefault();
Wenn Sie auf das Eingabefeld klicken, treten folgende Ereignisse auf - in der Reihenfolge, in der sie hier angezeigt werden:
mousedown
focus
(vorher löst ein anderes Objekt, das den Fokus verliert, ein blur
)mouseup
click
Wenn Sie versuchen, zu verhindern, dass das Element einen Eingabefokus erhält, hilft es uns nicht, Event-Handler zu verwenden, die mit dem
focus
Event-Handler beginnen.
Frage Nummer 5. Stoppen Sie die GIF-Animation und die ESC-Taste
Wie gehe ich mit dem Problem um, die GIF-Animation beim Drücken der ESC-Taste zu stoppen?
▍ Antwort
Hier können Sie den gleichen Ansatz verwenden, den wir oben betrachtet haben. In einigen Browsern werden durch Drücken der ESC-Taste die GIF-Animation und das Laden von Seiten gestoppt. Dies ist ihr Standardverhalten. Um zu verhindern, dass sie sich auf diese Weise verhalten, ist die Ereignismethode
preventDefault()
für uns nach wie vor hilfreich. Der ESC-Schlüsselcode lautet 27.
Frage Nummer 6. Klammern in IIFE
Wie werden die beiden Klammern verwendet, um einen sofort aufgerufenen Funktionsausdruck (IIFE) zu deklarieren?
▍ Antwort
Klammern in dieser Situation ermöglichen es dem Parser zu verstehen, dass vor ihnen eine Funktion ausgeführt werden muss. Er muss aber auch verstehen, was diese Klammern sind - der Gruppierungsoperator oder eine Konstruktion, die angibt, dass die Funktion aufgerufen werden muss. Wenn wir beispielsweise zwei Klammern verwenden, wie unten gezeigt, tritt ein
SyntaxError
Fehler auf:
function () {
Dies liegt daran, dass die Funktion keinen Namen hat (Sie müssen ihre Namen in Funktionsdeklarationen angeben).
Versuchen wir, diesen Code neu zu schreiben und der Funktion einen Namen zu geben:
function foo() {
Nun, da die Funktion einen Namen hat, sollte diese Konstruktion aus Sicht des Systems theoretisch ganz normal aussehen. Der Fehler verschwindet jedoch nicht, obwohl er jetzt mit dem Gruppierungsoperator zu tun hat, in dem sich kein Ausdruck befindet. Beachten Sie, dass in diesem Fall der Gruppierungsanweisung der Gruppierungsoperator folgt und keine Folge von Klammern, die dem System mitteilt, dass die vorhergehende Funktion aufgerufen werden muss.
Oft ist IIFE wie folgt aufgebaut:
(function () {
Es gibt aber auch andere Möglichkeiten, deren Kern es ist, dem Parser irgendwie anzuzeigen, dass es sich zuvor nur um einen funktionalen Ausdruck handelt, der ausgeführt werden muss:
!function () {
IIFE werden häufig in der JavaScript-Programmierung verwendet. Dieses Konstrukt wird beispielsweise in jQuery verwendet. Mit seiner Hilfe können Sie Verschlüsse erstellen. In der Tat sprechen wir über die Tatsache, dass der Programmierer mit IIFE Code im lokalen Bereich ausführen kann. Dies trägt zum Schutz des globalen Bereichs vor Verschmutzung bei und ermöglicht die Optimierung des Zugriffs auf globale Variablen. Solche Designs sind gut minimiert.
Frage Nummer 7. Code als Antwort auf Anfragen übergeben
Der Server sendet
alert ('Boom !!!');
der AJAX-Interaktion mit dem Client im Hauptteil der Antwort dem Client eine
alert ('Boom !!!');
. Der Client akzeptiert die Antwort und führt diesen Code mit der Funktion
eval()
aus. Wie heißt es? Schließlich ist in der Serverantwort nicht JSON, nicht XML und nicht HTML enthalten. Was können Sie über die Ausführung des vom Server kommenden Clients auf dem Client in Form des Hauptteils der Antwort auf eine bestimmte Anforderung sagen?
▍ Antwort
Tatsächlich gibt es keinen speziellen Namen für ein solches Schema für die Client-Server-Interaktion. Und dies ist ein Systeminteraktionsschema, von dem dringend abgeraten wird. Dies ist genauso schlecht wie das Speichern von PHP-Code in einer Datenbank und das anschließende Ausführen mit geeigneten Sprachmethoden. Selbst wenn wir ideologische Überlegungen nicht berücksichtigen, können wir sagen, dass eine solche Architektur äußerst unflexibel ist. Wenn also das Projekt, in dem sie verwendet wird, während der Entwicklung notwendig ist, etwas zu ändern, wird dies nicht einfach sein. Hier sehen wir ein Beispiel für eine schlechte Systemarchitektur, wenn Daten mit Code- und Schnittstellenelementen gemischt werden. Um etwas in einem solchen System zu ändern, müssen Sie zuerst die Feinheiten seiner komplizierten Architektur verstehen und dann nach den Änderungen wieder alles „verwirren“. Ich spreche nicht von Code-Wiederverwendung.
Um die Codeunterstützung zu vereinfachen, müssen Sie eine größtmögliche Trennung der Teile des Systems anstreben und die Anzahl der Abhängigkeiten dieser Teile verringern. Um eine schlechte Konnektivität von Teilen des Systems sicherzustellen, dh um sicherzustellen, dass ein Fragment der Anwendung daraus extrahiert oder mit der geringsten Komplexität durch ein anderes ersetzt werden kann, können Sie Ereignismechanismen oder spezielle Architekturlösungen wie MVC verwenden.
Frage Nummer 8. Durchführen schwerer Operationen im Hauptfaden
Wie kann man die Ausführung bestimmter ressourcenintensiver Befehle in JavaScript organisieren und nicht das gesamte Skript "aussetzen"?
▍ Antwort
JavaScript ist eine Single-Threaded-Sprache. Webseitencode wird im selben Thread ausgeführt und DOM-Baumtransformationen werden durchgeführt. Es gibt auch Timer. Jedes Mal, wenn Sie einige ressourcenintensive Vorgänge ausführen (Zyklen, Aufrufe "schwerer" Funktionen), führt dies zu einer Verlangsamung der Benutzeroberfläche oder sogar zu deren vollständiger Blockierung. Wenn die ausgeführten Vorgänge das System nicht besonders stark belasten, sind ihre Auswirkungen auf die Benutzeroberfläche so gering, dass Benutzer sie einfach nicht bemerken. Um Heavy Computing außerhalb des Hauptthreads zu erstellen, wurde das Konzept der Web-Worker in JavaScript eingeführt.
Wenn der Einsatz von Arbeitern nicht möglich ist, müssen Sie die Zyklen und "schweren" Funktionen optimieren. In dem Buch „JavaScript. Leistungsoptimierung “Nicholas Zakas sagt, dass der Benutzer nichts bemerkt, wenn der Fluss der Benutzeroberfläche für 100 ms oder weniger blockiert wird.
Aus dieser Idee können wir schließen, dass ressourcenintensive Berechnungen in Fragmente unterteilt werden können, deren Implementierung maximal 100 ms dauert. Danach muss der Hauptthread freigegeben werden.
Hier ist ein Beispielcode aus dem obigen Buch:
function timedProcessArray(items, process, callback) { var todo = items.concat();
Die Funktion
timedProcessArray()
blockiert den Hauptthread für 25 ms, führt eine Folge von Aktionen aus und gibt sie dann für 25 ms frei. Danach wird dieser Vorgang wiederholt.
Frage Nummer 9. Informationen zum Ändern der Größe des Browserfensters
Kann ich irgendwie herausfinden, dass der Benutzer die Größe des Browserfensters geändert hat?
▍ Antwort
Es gibt kein besonderes Ereignis, bei dem Sie es herausfinden können. Sie können jedoch mithilfe des Ereignisses
onresize
herausfinden, ob der Benutzer die Fenstergröße
onresize
. Diese Methode ist jedoch nicht sehr genau.
Hier ist ein Codeentwurf zur Lösung dieses Problems.
var time = 0, timerId, TIME_ADMISSION = 100;
Frage Nummer 10. Öffnen neuer Browserfenster und Registerkarten
Wie kann mit der Methode
window.open()
ein neues Browserfenster und kein neuer Tab geöffnet werden?
▍ Antwort
Wie genau sich die
window.open()
-Methode verhält, hängt vom Browser ab. Opera öffnet immer neue Registerkarten (obwohl sie wie Fenster aussehen), Safari öffnet immer Fenster (obwohl dieses Verhalten geändert werden kann). Das Verhalten von Chrome, Firefox und Internet Explorer kann gesteuert werden.
Wenn also ein zusätzlicher Parameter (Fensterposition
window.open()
an die
window.open()
-Methode übergeben wird, wird ein neues Fenster geöffnet:
window.open('http://www.google.com', '_blank', 'toolbar=0,location=0,menubar=0');
Wenn nur ein Link zu dieser Methode übergeben wird, wird eine neue Browser-Registerkarte geöffnet:
window.open('http://www.google.com');
Oft müssen Sie eine neue Browser-Registerkarte öffnen. Möglicherweise gibt es Probleme damit im Safari-Browser. Standardmäßig (abhängig von den Einstellungen) öffnet der Browser beim
window.open()
ein neues Fenster. Wenn Sie jedoch auf den Link klicken und die Tasten
Ctrl + Shift/Meta + Shift
drücken, wird eine neue Registerkarte geöffnet (unabhängig von den Einstellungen). Im folgenden Beispiel simulieren wir das Klickereignis, das
click
wird, wenn die Tasten
Ctrl + Shift/Meta + Shift
gedrückt werden:
function safariOpenWindowInNewTab (href) { var event = document.createEvent ('MouseEvents'), mac = (navigator.userAgent.indexOf ('Macintosh')> = 0);
Frage Nr. 11. Objekte tief kopieren
Wie kann man das tiefe Kopieren von Objekten effektiv organisieren?
▍ Antwort
Wenn sich das Objekt, dessen Kopie Sie erstellen möchten (nennen wir es
oldObject
), nicht ändert, ist es am effektivsten, dies über den Prototyp zu tun (dies geschieht sehr schnell):
function object(o) { function F() {} F.prototype = o; return new F(); } var newObject = object(oldObject);
Wenn Sie den Vorgang des Klonens eines Objekts wirklich ausführen müssen, ist der schnellste Weg rekursiv, diesen Prozess zu optimieren und seine Eigenschaften durchzugehen. Vielleicht ist dies der schnellste Algorithmus zum Erstellen tiefer Kopien von Objekten:
var cloner = { _clone: function _clone(obj) { if (obj instanceof Array) { var out = []; for (var i = 0, len = obj.length; i < len; i++) { var value = obj[i]; out[i] = (value !== null && typeof value === "object") ? _clone(value) : value; } } else { var out = {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { var value = obj[key]; out[key] = (value !== null && typeof value === "object") ? _clone(value) : value; } } } return out; }, clone: function(it) { return this._clone({ it: it }).it; } }; var newObject = cloner.clone(oldObject);
Wenn Sie jQuery verwenden, können Sie auf die folgenden Konstrukte zurückgreifen:
Frage Nummer 12. JavaScript-Destruktoren
Wie erstelle ich so etwas wie einen Destruktor in JavaScript? Wie verwalte ich den Lebenszyklus von Objekten?
▍ Antwort
In JavaScript wird ein Objekt aus dem Speicher gelöscht, nachdem der letzte Verweis darauf verschwunden ist:
var a = {z: 'z'}; var b = a; var c = a; delete az; delete a;
Die Verwendung eines „Destruktors“ in JavaScript führt nur zum Löschen des Inhalts des Objekts, nicht jedoch zum Löschen aus dem Speicher.
Frage Nummer 13. Binäre Datenverarbeitung
Ist es möglich, Binärdaten in JavaScript zu verarbeiten? Und wenn ja, wie?
▍ Antwort
Wenn Sie in einer JavaScript-Anwendung mit Binärdaten arbeiten müssen, können Sie versuchen, die
Binary Parser- Bibliothek zu verwenden. Aber ihr Code ist die Hölle. In ES6 + gibt es einen Vorschlag zum
StructType
Typ (dies ist dasselbe, was in C ++ durch den zusammengesetzten Datentyp von
struct
). Dieser Datentyp wird benötigt, um das Arbeiten mit Binärdaten zu vereinfachen. Die Arbeit damit könnte ungefähr so aussehen:
const Point2D = new StructType({ x: uint32, y: uint32 }); const Color = new StructType({ r: uint8, g: uint8, b: uint8 }); const Pixel = new StructType({ point: Point2D, color: Color }); const Triangle = new ArrayType(Pixel, 3); let t = new Triangle([{ point: { x: 0, y: 0 }, color: { r: 255, g: 255, b: 255 } }, { point: { x: 5, y: 5 }, color: { r: 128, g: 0, b: 0 } }, { point: { x: 10, y: 0 }, color: { r: 0, g: 0, b: 128 } }]);
Frage Nummer 14. Ändern von Variablen in einer Funktion von einer anderen Funktion
Wie ändere ich Variablen in einer Funktion von einer anderen Funktion?
▍ Antwort
Hier können Sie verschiedene Ansätze anwenden:
- Sie können den Link zum Kontext der für uns interessanten Funktion (die Funktion
primer()
im folgenden Beispiel) in der Funktion smth()
verwenden.
- Sie können eine im Kontext der Funktion
primer()
Funktion an die Funktion smth()
.
var primer = function () { var a, b, c, d, e = {}; smth (function () { a = 1; b = 2; c = 3; d = 4; }, e); alert ([a, b, c, d, e.pewpew]); }, smth = function (callback, e) { callback (); e.pewpew = "pewpew"; }; primer ();
- Früher (vor Firefox 3.6) konnten Sie mit der Eigenschaft
__parent__
zum Kontext __parent__
, aber bereits in Firefox 4 wurde diese Funktion entfernt.
Frage Nummer 15. Mit Funktionen arbeiten
Sagen Sie uns, wie Funktionen in JavaScript aufgerufen werden können.
▍ Antwort
Ich nehme an, es besteht keine Notwendigkeit, darüber zu sprechen, wie Funktionen, Methoden und Konstruktoren während der normalen Arbeit mit ihnen aufgerufen werden. Lassen Sie uns über die Verwendung der Methoden
call()
und
apply()
sprechen.
Verwenden von call () zum Konfigurieren des Konstruktors eines Objekts
Konvertieren Sie Array-ähnliche Objekte in Arrays
Array-ähnliche Objekte ähneln JavaScript-Arrays, sind es jedoch nicht. Dies drückt sich insbesondere darin aus, dass solche Objekte keine Methoden für gewöhnliche Arrays haben. Unter solchen Objekten können beispielsweise das
arguments
traditioneller Funktionen und die Ergebnisse der Methode
getElementsByTagName () notiert werden.
Erstellen von Wrapper-Objekten
Mit dieser Technik der Verwendung von
call()
und
apply()
können Sie Wrapper-Objekte erstellen. , -
foo()
,
bar()
.
:
function bar () {console.log(arguments)}
Function.call.apply()
:
function foo() { Function.call.apply(bar, arguments); }
,
Function.call.apply()
, ,
foo()
,
bar
.
№16.
, , ?
▍
. , Firefox 3.6,
__parent__
, .
№17.
, , ,
eval()
?
▍
, . , :
№18.
, JavaScript, , ?
▍
JavaScript - « ». . . , :
$('#smth').click(function onSmthClick(event) { if (smth) {
— , . , 2 :
$('#smth'). click (function handler1 (event) { if (smth) {
№19.
JavaScript ? — , .
▍
click
«» DOM. (, , ).
// jQuery $(window).bind ('click', function (e) { console.log ('Clicked on', e.target); }); // $('#pewpew').delegate ('*', 'click', function(e) { console.log('Clicked on', e.target); }); // $('#pewpew').delegate('.pewpew', 'click', function (e) { console.log ('Clicked on element with .pewpew class name'); });
№20. XHR-
XHR- jQuery?
▍
, - :
function xhr(m, u, c, x) { with(new XMLHttpRequest) onreadystatechange = function (x) { readyState ^ 4 || c(x.target) }, open(m, u), send() }
- :
function xhr(m, u, c, x) { with(new(this.XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP")) onreadystatechange = function (x) { readyState ^ 4 || c(x) }, open(m, u), send() }
:
xhr('get', '//google.com/favicon.ico', function (xhr) { console.dir(xhr) });
№21. -
(reflow) (repaint) -?
▍
requestAnimationFrame()
, , setInterval()
setTimeout()
. , , , , , . , JavaScript- CSS- SVG-. , , , , , , . , , .- float- ( ).
- DOM. , , , DOM ( ).
- — . ( , , ). Hier ist ein Beispiel:
// element.style.left = "150px;"; // ... element.style.color = "green"; // , , element.setAttribute ('style', 'color: green; left: 150px');
- ( ).
- — (
style.display = "none"
). , .
, -, . , , , , .
- .
- DOM- ( — ).
Document.querySelectorAll()
firstElementChild
.- ,
document.getElementsByTagName()
( , DOM, ).
№22. Node.js
Node.js, , ?
▍
, ( PHP Apache). , , . Node.js — . , ,
cluster . (master) - (worker). , .
№23. runInNewContext() Node.js
runInNewContext()
Node.js.
▍
. , ( Node.js- Nodester). - ,
runInNewContext()
. , «», . «» , ,
runInNewContext()
.
Zusammenfassung
JavaScript . , - , .
Liebe Leser! , - , , JavaScript , ?
