


JavaScript neu denken. Teilweise Anwendung, referenzielle Transparenz und verzögerte Operationen
Hallo Leute! Als ich vor einiger Zeit die neuesten TC39-Vorschläge durchstöberte, stieß ich auf eines, das mich begeisterte – und ein wenig skeptisch machte. Es geht um eine teilweise Anwendungssyntax für JavaScript. Auf den ersten Blick scheint es die perfekte Lösung für viele häufig auftretende Programmierprobleme zu sein, aber als ich darüber nachdachte, wurde mir klar, dass es sowohl viel zu mögen als auch Raum für Verbesserungen gibt.
Noch besser: Diese Bedenken lösten eine völlig neue Idee aus, die JavaScript noch leistungsfähiger machen könnte. Lassen Sie mich Sie auf diese Reise mitnehmen, komplett mit realistischen Beispielen, wie diese Funktionen die Art und Weise, wie wir jeden Tag programmieren, verändern könnten.
TLDR: Der Artikel stammt aus meiner alten Ausgabe zum Vorschlag: https://github.com/tc39/proposal-partial-application/issues/53
Der Vorschlag
Mit der teilweisen Anwendung können Sie einige Argumente einer Funktion „voreinstellen“ und so eine neue Funktion zur späteren Verwendung zurückgeben. Unser aktueller Code sieht so aus:
const fetchWithAuth = (path: string) => fetch( { headers: { Authorization: "Bearer token" } }, path, ); fetchWithAuth("/users"); fetchWithAuth("/posts");
Der Vorschlag führt hierfür eine ~()-Syntax ein:
const fetchWithAuth = fetch~({ headers: { Authorization: "Bearer token" } }, ?); fetchWithAuth("/users"); fetchWithAuth("/posts");
Sehen Sie, was passiert? Die fetchWithAuth-Funktion füllt das Header-Argument vorab aus, sodass Sie nur die URL angeben müssen. Es ist wie .bind(), aber flexibler und einfacher zu lesen.
Der Vorschlag ermöglicht Ihnen auch die Verwendung von ? als Platzhalter für unbefüllte Argumente und ... für einen Restparameter. Zum Beispiel:
const sendEmail = send~(user.email, ?, ...); sendEmail("Welcome!", "Hello and thanks for signing up!"); sendEmail("Reminder", "Don't forget to confirm your email.");
Mir gefällt am besten, dass ich die Typanmerkungen nicht duplizieren muss!
Klingt nützlich, oder? Aber es gibt noch viel mehr zu entpacken.
Das Argument für referenzielle Transparenz
Beginnen wir mit einem praktischen Problempunkt: Funktionsabschlüsse und veraltete Variablenreferenzen.
Angenommen, Sie planen eine Benachrichtigung. Sie könnten so etwas schreiben:
function notify(state: { data?: Data }) { if (state.data) { setTimeout(() => alert(state.data), 1000) } }
Haben Sie das Problem bereits gesehen? Die Eigenschaft „data“ kann sich während des Timeouts ändern und die Warnung zeigt nichts an! Um dieses Problem zu beheben, muss die Wertreferenz explizit übergeben werden. Hoffentlich akzeptiert „setTimeout“ zusätzliche Argumente, um sie an den Rückruf zu übergeben:
function notify(state: { data?: Data }) { if (state.data) { setTimeout((data) => alert(data), 1000, state.data) } }
Nicht schlecht, aber es wird nicht allgemein von allen APIs unterstützt. Eine teilweise Anwendung könnte dieses Muster weitaus universeller machen:
function notify(state: { data?: Data }) { if (state.data) { setTimeout(alert~(state.data), 1000) } }
Durch das Sperren von state.data zum Zeitpunkt der Funktionserstellung vermeiden wir unerwartete Fehler aufgrund veralteter Referenzen.
Reduzierung wiederholter Berechnungen
Ein weiterer praktischer Vorteil der Teilanwendung besteht darin, dass redundante Arbeiten bei der Verarbeitung großer Datensätze entfallen.
Zum Beispiel haben Sie eine Mapping-Logik, die für jeden Iterationsschritt zusätzliche Daten berechnen muss:
const fetchWithAuth = (path: string) => fetch( { headers: { Authorization: "Bearer token" } }, path, ); fetchWithAuth("/users"); fetchWithAuth("/posts");
Das Problem liegt im Proxy-Zugriff auf this.some.another. Es ist ziemlich schwer, jeden Iterationsschritt aufzurufen. Es wäre besser, diesen Code wie folgt umzugestalten:
const fetchWithAuth = fetch~({ headers: { Authorization: "Bearer token" } }, ?); fetchWithAuth("/users"); fetchWithAuth("/posts");
Mit der teilweisen Anwendung können wir es weniger ausführlich machen:
const sendEmail = send~(user.email, ?, ...); sendEmail("Welcome!", "Hello and thanks for signing up!"); sendEmail("Reminder", "Don't forget to confirm your email.");
Durch das Einbinden gemeinsamer Berechnungen machen Sie den Code prägnanter und leichter verständlich, ohne dass die Leistung darunter leidet.
Warum neue Syntax hinzufügen?
Hier fing ich an, mir den Kopf zu zerbrechen. Während die vorgeschlagene Syntax elegant ist, verfügt JavaScript bereits über viele Operatoren. Besonders die Fragezeichenoperatoren? Das Hinzufügen von ~() kann das Erlernen und Parsen der Sprache erschweren.
Was wäre, wenn wir die gleiche Funktionalität erreichen könnten, ohne eine neue Syntax einzuführen?
Eine methodenbasierte Alternative
Stellen Sie sich vor, Function.prototype mit einer Tie-Methode zu erweitern:
function notify(state: { data?: Data }) { if (state.data) { setTimeout(() => alert(state.data), 1000) } }
Es ist etwas ausführlicher, vermeidet aber die Einführung eines völlig neuen Operators. Durch ein zusätzliches Sonderzeichen für Platzhalter können wir das Fragezeichen ersetzen.
function notify(state: { data?: Data }) { if (state.data) { setTimeout((data) => alert(data), 1000, state.data) } }
Es ist ein perfektes Polypiling ohne zusätzliche Komplexität in der Bauzeit!
function notify(state: { data?: Data }) { if (state.data) { setTimeout(alert~(state.data), 1000) } }
Aber das ist nur die Spitze des Eisbergs. Dadurch wird das Platzhalterkonzept über verschiedene APIs hinweg wiederverwendbar.
Lazy Operations: Noch weiter gehen
Hier wird es richtig interessant. Was wäre, wenn wir das Symbolkonzept erweitern würden, um Lazy Operations zu ermöglichen?
Beispiel 1: Kombination von .filter() und .map()
Angenommen, Sie bearbeiten eine Produktliste für eine E-Commerce-Website. Sie möchten nur reduzierte Artikel mit gerundeten Preisen anzeigen. Normalerweise würden Sie Folgendes schreiben:
class Store { data: { list: [], some: { another: 42 } } get computedList() { return this.list.map((el) => computeElement(el, this.some.another)) } contructor() { makeAutoObservable(this) } }
Dies erfordert jedoch eine zweimalige Iteration über das Array. Mit Lazy Operations könnten wir beide Schritte in einem Durchgang kombinieren:
class Store { data: { list: [], some: { another: 42 } } get computedList() { const { another } = this.some return this.list.map((el) => computeElement(el, another)) } contructor() { makeAutoObservable(this) } }
Symbol.skip weist die Engine an, Elemente aus dem endgültigen Array auszuschließen, wodurch der Vorgang sowohl effizient als auch ausdrucksstark wird!
Beispiel 2: Vorzeitige Beendigung in .reduce()
Stellen Sie sich vor, Sie berechnen den Gesamtumsatz aus den ersten fünf Verkäufen. Normalerweise würden Sie eine Bedingung innerhalb von .reduce():
verwenden
class Store { data: { list: [], some: { another: 42 } } get computedList() { return this.list.map(computeElement~(?, this.some.another)) } contructor() { makeAutoObservable(this) } }
Das funktioniert, verarbeitet aber trotzdem jedes Element im Array. Mit verzögerten Kürzungen könnten wir eine vorzeitige Kündigung signalisieren:
function notify(state: { data?: Data }) { if (state.data) { setTimeout(alert.tie(state.data), 1000) } }
Das Vorhandensein von Symbol.skip könnte der Engine mitteilen, dass sie die Iteration stoppen soll, sobald die Bedingung erfüllt ist, wodurch wertvolle Zyklen eingespart werden.
Warum das wichtig ist
Diese Ideen – teilweise Anwendung, referenzielle Transparenz und verzögerte Operationen – sind nicht nur akademische Konzepte. Sie lösen reale Probleme:
- Sauberere API-Nutzung: Argumente im Voraus sperren und veraltete Referenzen vermeiden.
- Verbesserte Leistung: Eliminieren Sie redundante Berechnungen und ermöglichen Sie eine effizientere Iteration.
- Größere Ausdruckskraft:Schreiben Sie prägnanten, deklarativen Code, der einfacher zu lesen und zu warten ist.
Ob wir bei ~() bleiben oder Alternativen wie tie und Symbol.skip erkunden, die zugrunde liegenden Prinzipien haben ein enormes Potenzial, die Art und Weise, wie wir JavaScript schreiben, zu verbessern.
Ich stimme für den Symbolansatz, da er leicht mehrfach auszufüllen ist und verschiedene Verwendungsmöglichkeiten bietet.
Was kommt als nächstes?
Ich bin neugierig – was denkst du? Ist ~() die richtige Richtung oder sollten wir methodenbasierte Ansätze erkunden? Und wie würden sich Lazy Operations auf Ihren Arbeitsablauf auswirken? Lasst uns in den Kommentaren diskutieren!
Das Schöne an JavaScript liegt in seiner von der Community vorangetriebenen Entwicklung. Indem wir Ideen austauschen und diskutieren, können wir eine Sprache entwickeln, die für alle besser funktioniert. Lassen Sie uns das Gespräch am Laufen halten!
Das obige ist der detaillierte Inhalt vonJavaScript neu denken. Teilweise Anwendung, referenzielle Transparenz und verzögerte Operationen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Häufig gestellte Fragen und Lösungen für das Ticket-Ticket-Ticket-Ticket in Front-End im Front-End-Entwicklungsdruck ist der Ticketdruck eine häufige Voraussetzung. Viele Entwickler implementieren jedoch ...

JavaScript ist der Eckpfeiler der modernen Webentwicklung. Zu den Hauptfunktionen gehören eine ereignisorientierte Programmierung, die Erzeugung der dynamischen Inhalte und die asynchrone Programmierung. 1) Ereignisgesteuerte Programmierung ermöglicht es Webseiten, sich dynamisch entsprechend den Benutzeroperationen zu ändern. 2) Die dynamische Inhaltsgenerierung ermöglicht die Anpassung der Seiteninhalte gemäß den Bedingungen. 3) Asynchrone Programmierung stellt sicher, dass die Benutzeroberfläche nicht blockiert ist. JavaScript wird häufig in der Webinteraktion, der einseitigen Anwendung und der serverseitigen Entwicklung verwendet, wodurch die Flexibilität der Benutzererfahrung und die plattformübergreifende Entwicklung erheblich verbessert wird.

Es gibt kein absolutes Gehalt für Python- und JavaScript -Entwickler, je nach Fähigkeiten und Branchenbedürfnissen. 1. Python kann mehr in Datenwissenschaft und maschinellem Lernen bezahlt werden. 2. JavaScript hat eine große Nachfrage in der Entwicklung von Front-End- und Full-Stack-Entwicklung, und sein Gehalt ist auch beträchtlich. 3. Einflussfaktoren umfassen Erfahrung, geografische Standort, Unternehmensgröße und spezifische Fähigkeiten.

Wie fusioniere ich Array -Elemente mit derselben ID in ein Objekt in JavaScript? Bei der Verarbeitung von Daten begegnen wir häufig die Notwendigkeit, dieselbe ID zu haben ...

JavaScript zu lernen ist nicht schwierig, aber es ist schwierig. 1) Verstehen Sie grundlegende Konzepte wie Variablen, Datentypen, Funktionen usw. 2) Beherrschen Sie die asynchrone Programmierung und implementieren Sie sie durch Ereignisschleifen. 3) Verwenden Sie DOM -Operationen und versprechen Sie, asynchrone Anfragen zu bearbeiten. 4) Vermeiden Sie häufige Fehler und verwenden Sie Debugging -Techniken. 5) Die Leistung optimieren und Best Practices befolgen.

Diskussion über die Realisierung von Parallaxe -Scrolling- und Elementanimationseffekten in diesem Artikel wird untersuchen, wie die offizielle Website der Shiseeido -Website (https://www.shiseeido.co.jp/sb/wonderland/) ähnlich ist ...

Zu den neuesten Trends im JavaScript gehören der Aufstieg von Typenkripten, die Popularität moderner Frameworks und Bibliotheken und die Anwendung der WebAssembly. Zukunftsaussichten umfassen leistungsfähigere Typsysteme, die Entwicklung des serverseitigen JavaScript, die Erweiterung der künstlichen Intelligenz und des maschinellen Lernens sowie das Potenzial von IoT und Edge Computing.

Eingehende Diskussion der Ursachen des Unterschieds in der Konsole.log-Ausgabe. In diesem Artikel wird die Unterschiede in den Ausgabeergebnissen der Konsolenfunktion in einem Code analysiert und die Gründe dafür erläutert. � ...
