suchen
HeimWeb-Frontendjs-TutorialJavaScript neu denken. Teilweise Anwendung, referenzielle Transparenz und verzögerte Operationen

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");

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!

Stellungnahme
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
JavaScript -Datentypen: Gibt es einen Unterschied zwischen Browser und NodeJs?JavaScript -Datentypen: Gibt es einen Unterschied zwischen Browser und NodeJs?May 14, 2025 am 12:15 AM

JavaScript -Kerndatentypen sind in Browsern und Knoten.js konsistent, werden jedoch unterschiedlich als die zusätzlichen Typen behandelt. 1) Das globale Objekt ist ein Fenster im Browser und global in node.js. 2) Node.js 'eindeutiges Pufferobjekt, das zur Verarbeitung von Binärdaten verwendet wird. 3) Es gibt auch Unterschiede in der Leistung und Zeitverarbeitung, und der Code muss entsprechend der Umgebung angepasst werden.

JavaScript -Kommentare: Eine Anleitung zur Verwendung // und / * * /JavaScript -Kommentare: Eine Anleitung zur Verwendung // und / * * /May 13, 2025 pm 03:49 PM

JavaScriptUSESTWOTYPESOFCOMMENMENTEN: Einzelzeilen (//) und Multi-Linie (//). 1) Verwendung // Forquicknotesorsingle-Linexplanationen.2 Verwendung // ForlongerExPlanationsCompomentingingoutblocks-

Python gegen JavaScript: Eine vergleichende Analyse für EntwicklerPython gegen JavaScript: Eine vergleichende Analyse für EntwicklerMay 09, 2025 am 12:22 AM

Der Hauptunterschied zwischen Python und JavaScript sind die Typ -System- und Anwendungsszenarien. 1. Python verwendet dynamische Typen, die für wissenschaftliche Computer- und Datenanalysen geeignet sind. 2. JavaScript nimmt schwache Typen an und wird in Front-End- und Full-Stack-Entwicklung weit verbreitet. Die beiden haben ihre eigenen Vorteile bei der asynchronen Programmierung und Leistungsoptimierung und sollten bei der Auswahl gemäß den Projektanforderungen entschieden werden.

Python vs. JavaScript: Auswählen des richtigen Tools für den JobPython vs. JavaScript: Auswählen des richtigen Tools für den JobMay 08, 2025 am 12:10 AM

Ob die Auswahl von Python oder JavaScript vom Projekttyp abhängt: 1) Wählen Sie Python für Datenwissenschafts- und Automatisierungsaufgaben aus; 2) Wählen Sie JavaScript für die Entwicklung von Front-End- und Full-Stack-Entwicklung. Python ist für seine leistungsstarke Bibliothek in der Datenverarbeitung und -automatisierung bevorzugt, während JavaScript für seine Vorteile in Bezug auf Webinteraktion und Full-Stack-Entwicklung unverzichtbar ist.

Python und JavaScript: Verständnis der Stärken der einzelnenPython und JavaScript: Verständnis der Stärken der einzelnenMay 06, 2025 am 12:15 AM

Python und JavaScript haben jeweils ihre eigenen Vorteile, und die Wahl hängt von den Projektbedürfnissen und persönlichen Vorlieben ab. 1. Python ist leicht zu erlernen, mit prägnanter Syntax, die für Datenwissenschaft und Back-End-Entwicklung geeignet ist, aber eine langsame Ausführungsgeschwindigkeit hat. 2. JavaScript ist überall in der Front-End-Entwicklung und verfügt über starke asynchrone Programmierfunktionen. Node.js macht es für die Entwicklung der Vollstapel geeignet, die Syntax kann jedoch komplex und fehleranfällig sein.

JavaScripts Kern: Ist es auf C oder C aufgebaut?JavaScripts Kern: Ist es auf C oder C aufgebaut?May 05, 2025 am 12:07 AM

JavaScriptisnotbuiltoncorc; Es ist angehört, dass sich JavaScriptWasdedeSthatrunsonGineoFtencninc.

JavaScript-Anwendungen: Von Front-End bis Back-EndJavaScript-Anwendungen: Von Front-End bis Back-EndMay 04, 2025 am 12:12 AM

JavaScript kann für die Entwicklung von Front-End- und Back-End-Entwicklung verwendet werden. Das Front-End verbessert die Benutzererfahrung durch DOM-Operationen, und die Back-End-Serveraufgaben über node.js. 1. Beispiel für Front-End: Ändern Sie den Inhalt des Webseitentextes. 2. Backend Beispiel: Erstellen Sie einen Node.js -Server.

Python vs. JavaScript: Welche Sprache sollten Sie lernen?Python vs. JavaScript: Welche Sprache sollten Sie lernen?May 03, 2025 am 12:10 AM

Die Auswahl von Python oder JavaScript sollte auf Karriereentwicklung, Lernkurve und Ökosystem beruhen: 1) Karriereentwicklung: Python ist für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet, während JavaScript für die Entwicklung von Front-End- und Full-Stack-Entwicklung geeignet ist. 2) Lernkurve: Die Python -Syntax ist prägnant und für Anfänger geeignet; Die JavaScript -Syntax ist flexibel. 3) Ökosystem: Python hat reichhaltige wissenschaftliche Computerbibliotheken und JavaScript hat ein leistungsstarkes Front-End-Framework.

See all articles

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ßer Artikel

Nordhold: Fusionssystem, erklärt
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
Mandragora: Flüstern des Hexenbaum
3 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

SublimeText3 Linux neue Version

SublimeText3 Linux neue Version

SublimeText3 Linux neueste Version

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

VSCode Windows 64-Bit-Download

VSCode Windows 64-Bit-Download

Ein kostenloser und leistungsstarker IDE-Editor von Microsoft

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)