Was ist der beste Weg, um das Überladen von Funktionen in Javascript vorzutäuschen?
Ich weiß, dass es nicht möglich ist, Funktionen in Javascript wie in anderen Sprachen zu überladen. Wenn ich eine Funktion mit zwei Verwendungszwecken brauchte foo(x)
und foo(x,y,z)
welche der beste / bevorzugte Weg ist:
- Verwenden Sie zunächst verschiedene Namen
- Mit optionalen Argumenten wie
y = y || 'default'
- Anzahl der Argumente verwenden
- Überprüfung der Argumenttypen
- Oder wie?
javascript
overloading
hamdiakoguz
quelle
quelle
Antworten:
Der beste Weg, um eine Funktionsüberladung mit Parametern durchzuführen, besteht darin, die Argumentlänge oder die Typen nicht zu überprüfen. Wenn Sie die Typen überprüfen, wird Ihr Code nur langsam und Sie haben Spaß an Arrays, Nullen, Objekten usw.
Die meisten Entwickler greifen ein Objekt als letztes Argument für ihre Methoden an. Dieses Objekt kann alles aufnehmen.
Dann können Sie damit umgehen, wie Sie es in Ihrer Methode wollen. [Switch, if-else usw.]
quelle
if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
arguments.length
nicht empfohlen? Außerdem war ich schon einmal hier und habe gelesen, was die meisten Entwickler tun, ist ... aber ich bin sicher, dass dies der einzige Ort ist, an dem ich das gesehen habe. Diese Methode verdirbt auch die syntaktische Zuckerhaftigkeit von "Überladungen"!Ich mache das oft:
C #:
JavaScript-Äquivalent:
Dieses spezielle Beispiel ist in Javascript tatsächlich eleganter als C #. Parameter, die nicht angegeben werden, sind in Javascript 'undefiniert', was in einer if-Anweisung als false ausgewertet wird. Die Funktionsdefinition vermittelt jedoch nicht die Information, dass p2 und p3 optional sind. Wenn Sie viel überladen müssen, hat jQuery beschlossen, ein Objekt als Parameter zu verwenden, z. B. jQuery.ajax (Optionen). Ich stimme ihnen zu, dass dies der leistungsstärkste und klar dokumentierbarste Ansatz zur Überladung ist, aber ich benötige selten mehr als ein oder zwei schnelle optionale Parameter.
BEARBEITEN: IF-Test gemäß Ians Vorschlag geändert
quelle
undefined
, sind in JS, nichtnull
. Als bewährte Methode sollten Sie niemals etwas festlegenundefined
, daher sollte dies kein Problem sein, solange Sie Ihren Test auf ändernp2 === undefined
.false
als letztes Argument übergeben, wird es nicht"false"
bis zum Ende verkettet , da dasif(p3)
nicht verzweigt wird.typeof p2 === "undefined"
sind wahrscheinlich das Gegenteil von dem, was Sie in Ihrem Beispiel erwarten. Ich denke, estypeof p2 !== "undefined"
ist das, was Sie beabsichtigt haben. Darf ich auch vorschlagen, dass es Zeichenfolge, Nummer und Booleschenp2 === "number"; p3 === "boolean"
===
und!==
? Warum nicht einfach==
und verwenden!=
?In JavaScript gibt es keine echte Funktionsüberladung, da eine beliebige Anzahl von Parametern eines beliebigen Typs übergeben werden kann. Sie müssen innerhalb der Funktion überprüfen, wie viele Argumente übergeben wurden und welchen Typ sie haben.
quelle
Die richtige Antwort lautet: ES GIBT KEINE ÜBERLASTUNG IN JAVASCRIPT.
Das Überprüfen / Schalten innerhalb der Funktion ist nicht ÜBERLASTET.
Das Konzept des Überladens: In einigen Programmiersprachen ist das Überladen von Funktionen oder das Überladen von Methoden die Möglichkeit, mehrere gleichnamige Methoden mit unterschiedlichen Implementierungen zu erstellen. Aufrufe einer überladenen Funktion führen eine bestimmte Implementierung dieser Funktion aus, die dem Kontext des Aufrufs entspricht, sodass ein Funktionsaufruf je nach Kontext unterschiedliche Aufgaben ausführen kann.
Beispielsweise sind doTask () und doTask (Objekt O) überladene Methoden. Um Letzteres aufzurufen, muss ein Objekt als Parameter übergeben werden, während Ersteres keinen Parameter benötigt und mit einem leeren Parameterfeld aufgerufen wird. Ein häufiger Fehler besteht darin, dem Objekt in der zweiten Methode einen Standardwert zuzuweisen, was zu einem mehrdeutigen Aufruffehler führen würde, da der Compiler nicht weiß, welche der beiden Methoden verwendet werden soll.
https://en.wikipedia.org/wiki/Function_overloading
Alle vorgeschlagenen Implementierungen sind großartig, aber um ehrlich zu sein, gibt es keine native Implementierung für JavaScript.
quelle
Es gibt zwei Möglichkeiten, wie Sie dies besser angehen können:
Übergeben Sie ein Wörterbuch (assoziatives Array), wenn Sie viel Flexibilität lassen möchten
Nehmen Sie ein Objekt als Argument und verwenden Sie die prototypbasierte Vererbung, um die Flexibilität zu erhöhen.
quelle
Hier ist ein Ansatz, der eine echte Methodenüberladung mithilfe von Parametertypen ermöglicht (siehe unten):
Bearbeiten (2018) : Seit dies im Jahr 2011 geschrieben wurde, hat die Geschwindigkeit direkter Methodenaufrufe stark zugenommen, während die Geschwindigkeit überladener Methoden dies nicht getan hat.
Es ist kein Ansatz, den ich empfehlen würde, aber es ist eine lohnende Gedankenübung, darüber nachzudenken, wie Sie diese Art von Problemen lösen können.
Hier ist ein Benchmark der verschiedenen Ansätze - https://jsperf.com/function-overloading . Es zeigt, dass die Funktionsüberladung (unter Berücksichtigung von Typen) in Google Chrome V8 ab 16.0 (Beta) etwa 13-mal langsamer sein kann .
Neben der Übergabe eines Objekts (dh
{x: 0, y: 0}
) kann bei Bedarf auch der C-Ansatz gewählt werden, wobei die Methoden entsprechend benannt werden. Zum Beispiel Vector.AddVector (Vektor), Vector.AddIntegers (x, y, z, ...) und Vector.AddArray (integerArray). Sie können sich C-Bibliotheken wie OpenGL ansehen, um Inspiration für die Benennung zu erhalten.Bearbeiten : Ich habe einen Benchmark zum Übergeben eines Objekts und zum Testen des Objekts mit beiden
'param' in arg
und hinzugefügtarg.hasOwnProperty('param')
, und das Überladen von Funktionen ist viel schneller als das Übergeben eines Objekts und das Überprüfen auf Eigenschaften (zumindest in diesem Benchmark).Aus Entwurfssicht ist die Funktionsüberladung nur dann gültig oder logisch, wenn die überladenen Parameter derselben Aktion entsprechen. Es liegt also nahe, dass es eine zugrunde liegende Methode geben sollte, die sich nur mit bestimmten Details befasst, andernfalls kann dies auf unangemessene Entwurfsentscheidungen hinweisen. Man könnte also auch die Verwendung von Funktionsüberladung auflösen, indem man Daten in ein entsprechendes Objekt konvertiert. Natürlich muss man den Umfang des Problems berücksichtigen, da keine aufwändigen Entwürfe erforderlich sind, wenn Sie nur einen Namen drucken möchten, aber für den Entwurf von Frameworks und Bibliotheken sind solche Überlegungen gerechtfertigt.
Mein Beispiel stammt aus einer Rechteck-Implementierung - daher die Erwähnung von Dimension und Punkt. Vielleicht ein Rechteck könnte hinzufügen
GetRectangle()
Methode derDimension
undPoint
Prototyp, und dann die Funktion Ausgabe Überlastung wird sortiert. Und was ist mit Primitiven? Nun, wir haben eine Argumentlänge, die jetzt ein gültiger Test ist, da Objekte eineGetRectangle()
Methode haben.quelle
Der beste Weg hängt wirklich von der Funktion und den Argumenten ab. Jede Ihrer Optionen ist in verschiedenen Situationen eine gute Idee. Ich versuche diese im Allgemeinen in der folgenden Reihenfolge, bis einer von ihnen funktioniert:
Verwenden optionaler Argumente wie y = y || 'Standard'. Dies ist praktisch, wenn Sie dies tun können, funktioniert jedoch möglicherweise nicht immer praktisch, z. B. wenn 0 / null / undefined ein gültiges Argument wäre.
Anzahl der Argumente verwenden. Ähnlich wie die letzte Option, funktioniert jedoch möglicherweise, wenn # 1 nicht funktioniert.
Überprüfung der Argumenttypen. Dies kann in einigen Fällen funktionieren, in denen die Anzahl der Argumente gleich ist. Wenn Sie die Typen nicht zuverlässig bestimmen können, müssen Sie möglicherweise andere Namen verwenden.
Verwenden Sie zunächst verschiedene Namen. Möglicherweise müssen Sie dies tun, wenn die anderen Optionen nicht funktionieren, nicht praktikabel sind oder mit anderen verwandten Funktionen übereinstimmen.
quelle
Das Problem ist, dass JavaScript das Überladen von Methoden NICHT nativ unterstützt. Wenn also zwei oder mehr Funktionen mit demselben Namen angezeigt / analysiert werden, wird nur die zuletzt definierte Funktion berücksichtigt und die vorherigen überschrieben.
Eine der Möglichkeiten, die meiner Meinung nach für den größten Teil des Falls geeignet sind, ist folgende:
Nehmen wir an, Sie haben eine Methode
Anstatt eine Methode zu überladen, die in Javascript nicht möglich ist, können Sie eine neue Methode definieren
und ändern Sie dann die 1. Funktion wie folgt -
Wenn Sie viele solcher überladenen Methoden haben, sollten Sie
switch
nicht nurif-else
Anweisungen verwenden.( mehr Details )
PS: Der obige Link führt zu meinem persönlichen Blog, der zusätzliche Details enthält.
quelle
Ich bin mir über Best Practices nicht sicher, aber hier ist, wie ich es mache:
quelle
Ich habe es gerade versucht, vielleicht passt es zu Ihren Bedürfnissen. Abhängig von der Anzahl der Argumente können Sie auf eine andere Funktion zugreifen. Sie initialisieren es beim ersten Aufruf. Und die Funktionskarte ist im Verschluss versteckt.
Probier es aus.
quelle
Da JavaScript keine Funktionsüberladungsoptionen hat, kann stattdessen ein Objekt verwendet werden. Wenn ein oder zwei Argumente erforderlich sind, ist es besser, sie vom Optionsobjekt zu trennen. Hier ist ein Beispiel für die Verwendung des Optionsobjekts und der aufgefüllten Werte als Standardwert, falls im Optionsobjekt kein Wert übergeben wurde.
Hier ist ein Beispiel für die Verwendung des Optionsobjekts
quelle
Es gibt keine Möglichkeit, eine Überladung in Javascript zu funktionieren. Daher empfehle ich die folgende
typeof()
Methode anstelle der Mehrfachfunktion, um eine Überladung vorzutäuschen.Viel Glück!
quelle
var type = typeof param; if (type === 'string') ...
EINFÜHRUNG
Bisher würde das Durchlesen so vieler Antworten jedem Kopfschmerzen bereiten. Jeder, der versucht, das Konzept zu kennen, muss die folgenden Voraussetzungen kennen .
Function overloading Definition
,Function Length property
,Function argument property
Function overloading
In seiner einfachsten Form bedeutet dies, dass eine Funktion verschiedene Aufgaben basierend auf der Anzahl der Argumente ausführt, die an sie übergeben werden. Insbesondere sind TASK1, TASK2 und TASK3 unten hervorgehoben und werden auf der Grundlage der Anzahl ausgeführtarguments
, die an dieselbe Funktion übergeben werdenfooYo
.HINWEIS - JS bietet keine eingebaute Fähigkeit zur Funktionsüberladung.
Alternative
John E Resig (Erfinder von JS) hat eine Alternative aufgezeigt, die die oben genannten Voraussetzungen nutzt, um die Fähigkeit zur Implementierung einer Funktionsüberladung zu erreichen.
Der folgende Code verwendet einen einfachen, aber naiven Ansatz unter Verwendung von
if-else
oderswitch
Anweisung.argument-length
Eigenschaft.Eine andere Technik ist viel sauberer und dynamischer. Das Highlight dieser Technik ist die
addMethod
generische Funktion.Wir definieren eine Funktion
addMethod
, mit der einem Objekt mit demselben Namen, aber unterschiedlichen Funktionen verschiedene Funktionen hinzugefügt werden .Unterhalb der
addMethod
Funktion werden drei Parameter Objektnameobject
, Funktionsnamename
und die Funktion akzeptiert , die aufgerufen werden sollfn
.addMethod
Definition wirdvar old
der Verweis auf den vorherigenfunction
gespeichert, der mithilfe des Verschlusses gespeichert wird - eine Schutzblase.addMethod
drei Funktionen hinzugefügt, die beim Aufrufenninja.whatever(x)
mit der Anzahl der Argumente,x
die beliebig sein können, dh entweder leer oder mit einem oder mehreren Argumenten , verschiedene Funktionen aufrufen, die unter Verwendung deraddMethod
Funktion definiert wurden.quelle
Eine andere Möglichkeit, dies zu erreichen, ist die Verwendung der speziellen Variablen: Argumente . Dies ist eine Implementierung:
So können Sie diesen Code ändern in:
quelle
Schau dir das an. Es ist sehr cool. http://ejohn.org/blog/javascript-method-overloading/ Trick Javascript, damit Sie Anrufe wie diesen tätigen können:
quelle
Func(new Point())
undFunc(new Rectangle())
werde verschiedene Funktionen ausführen. Aber ich muss darauf hinweisen, dass dies ein schmutziger Hack ist, da das Überladen von Methoden wirklich eine Aufgabe zur Kompilierungszeit und keine Laufzeit ist.Funktionsüberladung in Javascript:
Funktionsüberladung ist die Fähigkeit einer Programmiersprache, mehrere gleichnamige Funktionen mit unterschiedlichen Implementierungen zu erstellen. Wenn eine überladene Funktion aufgerufen wird, führt sie eine spezifische Implementierung dieser Funktion aus, die dem Kontext des Aufrufs entspricht. Dieser Kontext ist normalerweise die Anzahl der empfangenen Argumente und ermöglicht es einem Funktionsaufruf, sich je nach Kontext unterschiedlich zu verhalten.
Javascript verfügt nicht über eine integrierte Funktionsüberladung. Dieses Verhalten kann jedoch auf viele Arten emuliert werden. Hier ist eine bequeme einfache:
In Szenarien, in denen Sie nicht wissen, wie viele Argumente Sie erhalten, können Sie den Restoperator verwenden, der aus drei Punkten besteht
...
. Der Rest der Argumente wird in ein Array konvertiert. Achten Sie jedoch auf die Browserkompatibilität. Hier ist ein Beispiel:quelle
Da dieser Beitrag bereits viele verschiedene Lösungen enthält, dachte ich, ich poste eine andere.
Dies kann wie folgt verwendet werden:
Diese Lösung ist nicht perfekt, aber ich möchte nur zeigen, wie es gemacht werden kann.
quelle
Sie können die 'addMethod' von John Resig verwenden. Mit dieser Methode können Sie Methoden basierend auf der Anzahl der Argumente "überladen".
Ich habe auch eine Alternative zu dieser Methode erstellt, die Caching verwendet, um die Variationen der Funktion zu speichern. Die Unterschiede werden hier beschrieben
quelle
Weiterleitungsmuster => die beste Vorgehensweise bei JS-Überladung
Weiterleiten an eine andere Funktion, deren Name aus dem 3. und 4. Punkt besteht:
Bewerbung für Ihren Fall:
Andere komplexe Probe:
quelle
Funktionsüberladung durch dynamischen Polymorphismus in 100 Zeilen JS
Dies wird von einem größeren Körper von Code, der beinhaltet
isFn
,isArr
usw. Typen Prüffunktionen. Die folgende VanillaJS-Version wurde überarbeitet, um alle externen Abhängigkeiten zu entfernen. Sie müssen jedoch Ihre eigenen Typprüfungsfunktionen für die Verwendung in den.add()
Aufrufen definieren.Hinweis: Dies ist eine selbstausführende Funktion (so dass wir einen geschlossenen / geschlossenen Bereich haben können), daher die Zuordnung zu
window.overload
und nichtfunction overload() {...}
.Verwendungszweck:
Der Aufrufer definiert seine überladenen Funktionen, indem er der Rückgabe von eine Variable zuweist
overload()
. Dank der Verkettung können die zusätzlichen Überlastungen in Reihe definiert werden:Das einzige optionale Argument zum
overload()
Definieren der "Standard" -Funktion, die aufgerufen werden soll, wenn die Signatur nicht identifiziert werden kann. Die Argumente.add()
sind:fn
:function
Definieren der Überlast;a_vArgumentTests
:Array
offunction
s definiert die Tests, die auf dem ausgeführt werden sollenarguments
. Jederfunction
akzeptiert ein einzelnes Argument und gibttrue
Ihr Argument zurück, basierend darauf, ob das Argument gültig ist.sAlias
(Optional):string
Wenn Sie den Alias für den direkten Zugriff auf die Überladungsfunktion (fn
) definieren,myOverloadedFn.noArgs()
wird diese Funktion z. B. direkt aufgerufen, wobei die dynamischen Polymorphismustests der Argumente vermieden werden.Diese Implementierung ermöglicht tatsächlich mehr als nur herkömmliche Funktionsüberladungen, da das zweite
a_vArgumentTests
Argument.add()
in der Praxis benutzerdefinierte Typen definiert. Sie können also Argumente nicht nur anhand des Typs, sondern auch anhand von Bereichen, Werten oder Wertesammlungen steuern!Wenn Sie die 145 Codezeilen
overload()
durchsehen, werden Sie feststellen, dass jede Signatur nach der Anzahl derarguments
übergebenen Signaturen kategorisiert ist . Dies geschieht, damit wir die Anzahl der durchgeführten Tests begrenzen. Ich verfolge auch die Anzahl der Anrufe. Mit etwas zusätzlichem Code könnten die Arrays überladener Funktionen neu sortiert werden, sodass häufig aufgerufene Funktionen zuerst getestet werden, wodurch wiederum ein gewisses Maß an Leistungssteigerung hinzugefügt wird.Nun, es gibt einige Einschränkungen ... Da Javascript lose geschrieben ist, müssen Sie vorsichtig mit Ihrem sein,
vArgumentTests
dainteger
es alsfloat
usw. validiert werden könnte .JSCompress.com-Version (1114 Byte, 744 Byte mit G-ZIP):
quelle
Sie können jetzt in ECMAScript 2018 eine Funktionsüberladung durchführen, ohne Polyfills zu erstellen, die Länge / den Typ var zu überprüfen usw. Verwenden Sie einfach die Spread-Syntax .
Was ist Spread-Syntax?
Hinweis: Die Spread-Syntax in Objektliteralen funktioniert in Edge und IE nicht und ist eine experimentelle Funktion. Siehe Browserkompatibilität
quelle
So etwas kann zur Funktionsüberlastung durchgeführt werden.
Quelle
quelle
Dies ist eine alte Frage, aber eine, von der ich denke, dass sie einen anderen Eintrag benötigt (obwohl ich bezweifle, dass jemand sie lesen wird). Die Verwendung von sofort aufgerufenen Funktionsausdrücken (IIFE) kann in Verbindung mit Schließungen und Inline-Funktionen verwendet werden, um eine Funktionsüberladung zu ermöglichen. Betrachten Sie das folgende (erfundene) Beispiel:
Kurz gesagt, die Verwendung des IIFE schafft einen lokalen Bereich, der es uns ermöglicht, die private Variable
old
zu definieren , um einen Verweis auf die ursprüngliche Definition der Funktion zu speichernfoo
. Diese Funktion gibt dann eine Inline-Funktion zurücknewFoo
, die den Inhalt beider Argumente protokolliert, wenn genau zwei Argumente übergeben werden,a
undb
oder dieold
Funktion if aufruftarguments.length !== 2
. Dieses Muster kann beliebig oft wiederholt werden, um einer Variablen mehrere unterschiedliche Funktionsdefinitionen zu verleihen.quelle
Ich möchte ein nützliches Beispiel für einen überlasteten Ansatz nennen.
Verwendung: Clear (); // Löscht das gesamte Dokument
Löschen (myDiv); // Löscht das von myDiv referenzierte Bedienfeld
quelle
JavaScript ist eine untypisierte Sprache, und ich denke nur, dass es sinnvoll ist, eine Methode / Funktion in Bezug auf die Anzahl der Parameter zu überladen. Daher würde ich empfehlen zu überprüfen, ob der Parameter definiert wurde:
quelle
Ab Juli 2017 ist das Folgende die übliche Technik. Beachten Sie, dass wir auch innerhalb der Funktion eine Typprüfung durchführen können.
quelle
Für Ihren Anwendungsfall würde ich so vorgehen
ES6
(da es bereits Ende 2017 ist):Sie können dies natürlich anpassen, um mit einer beliebigen Anzahl von Parametern zu arbeiten, und einfach Ihre bedingten Anweisungen entsprechend ändern.
quelle
In JS gibt es keine tatsächliche Überladung. Trotzdem können wir die Methodenüberladung auf verschiedene Arten simulieren:
Methode 1: Objekt verwenden
Methode 2: Verwenden Sie Rest (Spread) -Parameter
Methode 3: Verwenden Sie undefiniert
Methode 4: Typprüfung
quelle
Die Standardparameter werden zwar nicht überladen, können jedoch einige der Probleme lösen, mit denen Entwickler in diesem Bereich konfrontiert sind. Die Eingabe wird streng von der Reihenfolge bestimmt, Sie können nicht wie bei der klassischen Überladung nachbestellen:
Ergebnisse in (für das Jahr 2020):
Weitere Informationen: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
quelle
Die erste Option verdient wirklich Aufmerksamkeit, da ich sie in einem recht komplexen Code-Setup gefunden habe. Meine Antwort lautet also
Mit einem kleinen, aber wesentlichen Hinweis sollten Namen für Computer anders aussehen, aber nicht für Sie. Nennen Sie überladene Funktionen wie: func, func1, func2.
quelle