Heim Web-Frontend js-Tutorial JavaScript neu denken. Teilweise Anwendung, referenzielle Transparenz und verzögerte Operationen

JavaScript neu denken. Teilweise Anwendung, referenzielle Transparenz und verzögerte Operationen

Dec 28, 2024 pm 05:34 PM

Rethinking JavaScript. Partial Application, Referential Transparency, and Lazy Operations

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");
Nach dem Login kopieren
Nach dem Login kopieren

Der Vorschlag führt hierfür eine ~()-Syntax ein:

const fetchWithAuth = fetch~({ headers: { Authorization: "Bearer token" } }, ?);
fetchWithAuth("/users");
fetchWithAuth("/posts");
Nach dem Login kopieren
Nach dem Login kopieren

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.");
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

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");
Nach dem Login kopieren
Nach dem Login kopieren

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");
Nach dem Login kopieren
Nach dem Login kopieren

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.");
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren

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)
  }
}
Nach dem Login kopieren

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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

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

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Was soll ich tun, wenn ich auf den Codendruck auf Kleidungsstücke für Front-End-Thermalpapier-Quittungen stoße? Was soll ich tun, wenn ich auf den Codendruck auf Kleidungsstücke für Front-End-Thermalpapier-Quittungen stoße? Apr 04, 2025 pm 02:42 PM

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 ...

Entmystifizieren JavaScript: Was es tut und warum es wichtig ist Entmystifizieren JavaScript: Was es tut und warum es wichtig ist Apr 09, 2025 am 12:07 AM

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.

Wer bekommt mehr Python oder JavaScript bezahlt? Wer bekommt mehr Python oder JavaScript bezahlt? Apr 04, 2025 am 12:09 AM

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 Arrayelemente mit derselben ID mit JavaScript in ein Objekt? Wie fusioniere ich Arrayelemente mit derselben ID mit JavaScript in ein Objekt? Apr 04, 2025 pm 05:09 PM

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 ...

Ist JavaScript schwer zu lernen? Ist JavaScript schwer zu lernen? Apr 03, 2025 am 12:20 AM

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.

Wie kann man Parallax -Scrolling- und Element -Animationseffekte wie die offizielle Website von Shiseido erzielen?
oder:
Wie können wir den Animationseffekt erzielen, der von der Seite mit der Seite mit der offiziellen Website von Shiseido begleitet wird? Wie kann man Parallax -Scrolling- und Element -Animationseffekte wie die offizielle Website von Shiseido erzielen? oder: Wie können wir den Animationseffekt erzielen, der von der Seite mit der Seite mit der offiziellen Website von Shiseido begleitet wird? Apr 04, 2025 pm 05:36 PM

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 ...

Die Entwicklung von JavaScript: Aktuelle Trends und Zukunftsaussichten Die Entwicklung von JavaScript: Aktuelle Trends und Zukunftsaussichten Apr 10, 2025 am 09:33 AM

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.

Der Unterschied in der Konsole.log -Ausgabeergebnis: Warum unterscheiden sich die beiden Anrufe? Der Unterschied in der Konsole.log -Ausgabeergebnis: Warum unterscheiden sich die beiden Anrufe? Apr 04, 2025 pm 05:12 PM

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. � ...

See all articles