Quelle (s) meilleure (s) manière (s) de simuler la surcharge de fonctions en Javascript?
Je sais qu'il n'est pas possible de surcharger les fonctions en Javascript comme dans d'autres langues. Si j'avais besoin d'une fonction à deux utilisations foo(x)
et foo(x,y,z)
qui est la meilleure / préférée:
- Utiliser des noms différents en premier lieu
- Utilisation d'arguments facultatifs comme
y = y || 'default'
- Utilisation d'un nombre d'arguments
- Vérification des types d'arguments
- Ou comment?
javascript
overloading
hamdiakoguz
la source
la source
Réponses:
La meilleure façon de surcharger les fonctions avec des paramètres n'est pas de vérifier la longueur des arguments ou les types; vérifier les types ne fera que ralentir votre code et vous vous amuserez avec les tableaux, les valeurs nulles, les objets, etc.
Ce que la plupart des développeurs font, c'est plaquer un objet comme le dernier argument de leurs méthodes. Cet objet peut contenir n'importe quoi.
Ensuite, vous pouvez le gérer comme vous le souhaitez dans votre méthode. [Switch, if-else, etc.]
la source
if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
arguments.length
n'est-elle pas recommandée? De plus, j'ai déjà été ici et j'ai lu ce que la plupart des développeurs font ... , mais je suis sûr que c'est le seul endroit où j'ai vu cela se faire. Cette méthode gâche également la douceur syntaxique d'avoir des «surcharges»!Je fais souvent ça:
C #:
Équivalent JavaScript:
Cet exemple particulier est en fait plus élégant en javascript que C #. Les paramètres qui ne sont pas spécifiés sont «non définis» en javascript, qui est évalué à faux dans une instruction if. Cependant, la définition de la fonction ne transmet pas les informations selon lesquelles p2 et p3 sont facultatifs. Si vous avez besoin de beaucoup de surcharge, jQuery a décidé d'utiliser un objet comme paramètre, par exemple, jQuery.ajax (options). Je suis d'accord avec eux qu'il s'agit de l'approche de surcharge la plus puissante et la plus clairement documentable, mais j'ai rarement besoin de plus d'un ou deux paramètres optionnels rapides.
EDIT: modification du test IF selon la suggestion de Ian
la source
undefined
en JS, nonnull
. En tant que meilleure pratique, vous ne devez jamais définir quoi que ce soitundefined
, donc cela ne devrait pas être un problème tant que vous changez votre test enp2 === undefined
.false
comme dernier argument, il ne sera pas concaténé"false"
à la fin, car laif(p3)
branche ne sera pas.typeof p2 === "undefined"
est probablement l'inverse de ce que vous attendez dans l'exemple de votre exemple, je pense quetypeof p2 !== "undefined"
c'est ce que vous vouliez. De plus, puis-je suggérer d'être censé concaténer la chaîne, le nombre et le booléen que vous faites réellementp2 === "number"; p3 === "boolean"
===
et!==
? Pourquoi ne pas simplement utiliser==
et!=
?Il n'y a pas de surcharge de fonction réelle en JavaScript car il permet de passer un nombre illimité de paramètres de tout type. Vous devez vérifier dans la fonction combien d' arguments ont été passés et de quel type ils sont.
la source
La bonne réponse est QU'IL N'Y A PAS DE SURCHARGE DANS JAVASCRIPT.
Vérifier / commuter à l'intérieur de la fonction n'est pas SURCHARGER.
Le concept de surcharge: Dans certains langages de programmation, la surcharge de fonctions ou la surcharge de méthodes est la possibilité de créer plusieurs méthodes du même nom avec différentes implémentations. Les appels à une fonction surchargée exécuteront une implémentation spécifique de cette fonction appropriée au contexte de l'appel, permettant à un appel de fonction d'effectuer différentes tâches selon le contexte.
Par exemple, doTask () et doTask (objet O) sont des méthodes surchargées. Pour appeler ce dernier, un objet doit être passé en paramètre, tandis que le premier ne nécessite pas de paramètre et est appelé avec un champ de paramètre vide. Une erreur courante serait d'attribuer une valeur par défaut à l'objet dans la deuxième méthode, ce qui entraînerait une erreur d'appel ambiguë, car le compilateur ne saurait pas laquelle des deux méthodes utiliser.
https://en.wikipedia.org/wiki/Function_overloading
Toutes les implémentations suggérées sont excellentes, mais à vrai dire, il n'y a pas d'implémentation native pour JavaScript.
la source
Il y a deux façons de mieux aborder cela:
Passez un dictionnaire (tableau associatif) si vous voulez laisser beaucoup de flexibilité
Prenez un objet comme argument et utilisez l'héritage basé sur un prototype pour ajouter de la flexibilité.
la source
Voici une approche qui permet une surcharge de méthode réelle à l'aide de types de paramètres, illustrés ci-dessous:
Edit (2018) : depuis que cela a été écrit en 2011, la vitesse des appels de méthode directe a considérablement augmenté alors que la vitesse des méthodes surchargées ne l'a pas fait.
Ce n'est pas une approche que je recommanderais, mais c'est un exercice de réflexion utile pour réfléchir à la façon de résoudre ces types de problèmes.
Voici une référence des différentes approches - https://jsperf.com/function-overloading . Cela montre que la surcharge des fonctions (en tenant compte des types) peut être environ 13 fois plus lente dans la version 8 de Google Chrome à partir de 16.0 (bêta) .
En plus de passer un objet (c'est-à-dire
{x: 0, y: 0}
), on peut également adopter l'approche C le cas échéant, en nommant les méthodes en conséquence. Par exemple, Vector.AddVector (vecteur), Vector.AddIntegers (x, y, z, ...) et Vector.AddArray (integerArray). Vous pouvez regarder les bibliothèques C, telles que OpenGL pour l'inspiration de nommage.Edit : J'ai ajouté un benchmark pour passer un objet et tester l'objet en utilisant les deux
'param' in arg
etarg.hasOwnProperty('param')
, et la surcharge de fonction est beaucoup plus rapide que de passer un objet et de vérifier les propriétés (dans ce benchmark au moins).Du point de vue de la conception, la surcharge de fonction n'est valide ou logique que si les paramètres surchargés correspondent à la même action. Il va donc de soi qu'il devrait y avoir une méthode sous-jacente qui ne concerne que des détails spécifiques, sinon cela pourrait indiquer des choix de conception inappropriés. Ainsi, on pourrait également résoudre l'utilisation de la surcharge de fonctions en convertissant les données en un objet respectif. Bien sûr, il faut considérer l'ampleur du problème car il n'est pas nécessaire de faire des conceptions élaborées si votre intention est simplement d'imprimer un nom, mais pour la conception de cadres et de bibliothèques, une telle pensée est justifiée.
Mon exemple vient d'une implémentation Rectangle - d'où la mention de Dimension et Point. Rectangle pourrait peut - être ajouter une
GetRectangle()
méthode auDimension
etPoint
prototype, puis la question de surcharge fonction est triée. Et les primitifs? Eh bien, nous avons la longueur d'argument, qui est maintenant un test valide car les objets ont uneGetRectangle()
méthode.la source
La meilleure façon dépend vraiment de la fonction et des arguments. Chacune de vos options est une bonne idée dans différentes situations. J'essaye généralement ceux-ci dans l'ordre suivant jusqu'à ce que l'un d'eux fonctionne:
Utilisation d'arguments optionnels comme y = y || 'défaut'. C'est pratique si vous pouvez le faire, mais cela peut ne pas toujours fonctionner pratiquement, par exemple quand 0 / null / undefined serait un argument valide.
Utilisation d'un certain nombre d'arguments. Similaire à la dernière option, mais peut fonctionner lorsque # 1 ne fonctionne pas.
Vérification des types d'arguments. Cela peut fonctionner dans certains cas où le nombre d'arguments est le même. Si vous ne pouvez pas déterminer de manière fiable les types, vous devrez peut-être utiliser des noms différents.
Utiliser des noms différents en premier lieu. Vous devrez peut-être le faire si les autres options ne fonctionnent pas, ne sont pas pratiques ou pour assurer la cohérence avec d'autres fonctions connexes.
la source
Le problème est que JavaScript ne prend pas en charge de manière native la surcharge de méthode. Donc, s'il voit / analyse deux fonctions ou plus avec les mêmes noms, il considérera simplement la dernière fonction définie et écrasera les précédentes.
Je pense que l'un des moyens qui convient à la plupart des cas est le suivant -
Disons que vous avez de la méthode
Au lieu de surcharger la méthode qui n'est pas possible en javascript, vous pouvez définir une nouvelle méthode
puis modifiez la 1ère fonction comme suit -
Si vous avez plusieurs de ces méthodes surchargées, envisagez d'utiliser plus
switch
que desif-else
instructions.( plus de détails )
PS: Le lien ci-dessus va à mon blog personnel qui contient des détails supplémentaires.
la source
Je ne suis pas sûr des meilleures pratiques, mais voici comment je le fais:
la source
Je viens d'essayer cela, peut-être que cela convient à vos besoins. Selon le nombre d'arguments, vous pouvez accéder à une fonction différente. Vous l'initialisez la première fois que vous l'appelez. Et la carte des fonctions est cachée dans la fermeture.
Essaye-le.
la source
Puisque JavaScript n'a pas d'options de surcharge de fonction, l'objet peut être utilisé à la place. S'il y a un ou deux arguments requis, il est préférable de les garder séparés de l'objet options. Voici un exemple sur la façon d'utiliser l'objet options et les valeurs remplies à la valeur par défaut au cas où la valeur n'a pas été transmise dans l'objet options.
voici un exemple sur la façon d'utiliser l'objet options
la source
Il n'y a aucun moyen de faire fonctionner la surcharge en javascript. Donc, je recommande comme la
typeof()
méthode suivante au lieu de plusieurs fonctions pour simuler la surcharge.Bonne chance!
la source
var type = typeof param; if (type === 'string') ...
INTRODUCTION
Jusqu'à présent, la lecture de tant de réponses donnerait mal à tout le monde. Quiconque essaie de connaître le concept devrait connaître les conditions préalables suivantes :
Function overloading Definition
,Function Length property
,Function argument property
Function overloading
dans sa forme la plus simple, une fonction exécute différentes tâches en fonction du nombre d'arguments qui lui sont transmis. Notamment, TASK1, TASK2 et TASK3 sont mis en évidence ci-dessous et sont exécutés sur la base du nombre de passagesarguments
à la même fonctionfooYo
.REMARQUE - JS ne fournit pas de capacité intégrée de surcharge de fonctions.
Alternative
John E Resig (créateur de JS) a souligné une alternative qui utilise les conditions préalables ci-dessus pour obtenir la capacité d'implémenter la surcharge de fonctions.
Le code ci-dessous utilise une approche simple mais naïve en utilisant
if-else
ou uneswitch
déclaration.argument-length
propriété.Une autre technique est beaucoup plus propre et dynamique. Le point culminant de cette technique est la
addMethod
fonction générique.nous définissons une fonction
addMethod
qui est utilisée pour ajouter différentes fonctions à un objet avec le même nom mais des fonctionnalités différentes .au-dessous de la
addMethod
fonction accepte trois nom d'objet paramsobject
, nom de fonctionname
et la fonction que nous voulons invoquerfn
.addMethod
définition intérieurevar old
stocke la référence au précédentfunction
stocké à l'aide de la fermeture - une bulle de protection.addMethod
ajout de trois fonctions qui, lorsqu'elles sont invoquées en utilisantninja.whatever(x)
avec le nombre d'argumentsx
qui peuvent être n'importe quoi, c'est-à-dire soit vide, soit une ou plusieurs invoque différentes fonctions telles que définies tout en utilisant laaddMethod
fonction.la source
Une autre façon d'aborder cela est d'utiliser la variable spéciale: arguments , c'est une implémentation:
vous pouvez donc modifier ce code pour:
la source
regarde ça. C'est très cool. http://ejohn.org/blog/javascript-method-overloading/ Trick Javascript pour vous permettre de faire des appels comme celui-ci:
la source
Func(new Point())
etFunc(new Rectangle())
exécuterai différentes fonctions. Mais je dois souligner qu'il s'agit d'un hack sale, car la surcharge de méthode est vraiment une tâche de compilation et non d'exécution.Surcharge de fonction en Javascript:
La surcharge de fonctions est la capacité d'un langage de programmation à créer plusieurs fonctions du même nom avec différentes implémentations. lorsqu'une fonction surchargée est appelée, elle exécute la fonction une implémentation spécifique de cette fonction appropriée au contexte de l'appel. Ce contexte est généralement la quantité d'arguments reçue, et il permet à un appel de fonction de se comporter différemment selon le contexte.
Javascript n'a pas de surcharge de fonction intégrée. Cependant, ce comportement peut être imité de plusieurs façons. En voici une simple et pratique:
Dans les scénarios où vous ne savez pas combien d'arguments vous obtiendrez, vous pouvez utiliser l' opérateur rest qui est de trois points
...
. Il convertira le reste des arguments en un tableau. Attention cependant à la compatibilité du navigateur. Voici un exemple:la source
Comme cet article contient déjà de nombreuses solutions différentes, j'ai pensé en poster une autre.
cela peut être utilisé comme indiqué ci-dessous:
Cette solution n'est pas parfaite mais je veux seulement montrer comment cela pourrait être fait.
la source
Vous pouvez utiliser le «addMethod» de John Resig. Avec cette méthode, vous pouvez "surcharger" les méthodes en fonction du nombre d'arguments.
J'ai également créé une alternative à cette méthode qui utilise la mise en cache pour contenir les variations de la fonction. Les différences sont décrites ici
la source
Modèle de transfert => la meilleure pratique de surcharge JS
Transférer à une autre fonction dont le nom est construit à partir des 3e et 4e points:
Application sur votre cas:
Autre échantillon complexe:
la source
Surcharge de fonction via le polymorphisme dynamique dans 100 lignes de JS
Ceci est d'un plus grand corps de code qui comprend les
isFn
,isArr
etc. fonctions de contrôle de type. La version VanillaJS ci-dessous a été retravaillée pour supprimer toutes les dépendances externes, mais vous devrez définir vos propres fonctions de vérification de type à utiliser dans les.add()
appels.Remarque: Il s'agit d'une fonction auto-exécutable (nous pouvons donc avoir une portée de fermeture / fermée), d'où l'affectation à
window.overload
plutôt qu'àfunction overload() {...}
.Usage:
L'appelant définit leurs fonctions surchargées en affectant une variable au retour de
overload()
. Grâce au chaînage, les surcharges supplémentaires peuvent être définies en série:Le seul argument facultatif pour
overload()
définir la fonction "par défaut" à appeler si la signature ne peut pas être identifiée. Les arguments pour.add()
sont:fn
:function
définition de la surcharge;a_vArgumentTests
:Array
defunction
s définir les tests à exécuter sur learguments
. Chacunfunction
accepte un seul argument et retournetrue
thy selon que l'argument est valide;sAlias
(Facultatif):string
définir l'alias pour accéder directement à la fonction de surcharge (fn
), par exemplemyOverloadedFn.noArgs()
, appellera cette fonction directement, en évitant les tests de polymorphisme dynamique des arguments.Cette implémentation permet en fait plus que de simples surcharges de fonctions traditionnelles, car le deuxième
a_vArgumentTests
argument.add()
définit en pratique les types personnalisés. Ainsi, vous pouvez générer des arguments non seulement en fonction du type, mais en fonction de plages, de valeurs ou de collections de valeurs!Si vous regardez à travers les 145 lignes de code,
overload()
vous verrez que chaque signature est classée par le nombre dearguments
passé. Ceci est fait de manière à limiter le nombre de tests que nous exécutons. Je garde également une trace du nombre d'appels. Avec du code supplémentaire, les tableaux de fonctions surchargées pourraient être triés de nouveau afin que les fonctions plus communément appelées soient testées en premier, ajoutant encore une certaine mesure d'amélioration des performances.Maintenant, il y a quelques mises en garde ... Comme Javascript est vaguement tapé, vous devrez faire attention à votre
vArgumentTests
comme uninteger
pourrait être validé comme unfloat
, etc.Version JSCompress.com (1114 octets, 744 octets g-zippés):
la source
Vous pouvez maintenant faire une surcharge de fonctions dans ECMAScript 2018 sans polyfills, vérifier la longueur / le type de var, etc., utilisez simplement la syntaxe de propagation .
Qu'est-ce que la syntaxe étalée?
Remarque: la syntaxe répartie dans les littéraux d'objet ne fonctionne pas dans Edge et IE et il s'agit d'une fonctionnalité expérimentale. voir la compatibilité du navigateur
la source
Quelque chose comme ça peut être fait pour la surcharge de fonctions.
La source
la source
C'est une vieille question mais qui, je pense, a besoin d'une autre entrée (bien que je doute que quelqu'un la lise). L'utilisation d'expressions de fonctions immédiatement appelées (IIFE) peut être utilisée conjointement avec des fermetures et des fonctions en ligne pour permettre une surcharge de fonctions. Prenons l'exemple (artificiel) suivant:
En bref, l'utilisation de l'IIFF crée une portée locale, nous permettant de définir la variable privée
old
pour stocker une référence à la définition initiale de la fonctionfoo
. Cette fonction renvoie ensuite une fonction en lignenewFoo
qui enregistre le contenu des deux arguments si elle est passée exactement deux argumentsa
etb
ou appelle laold
fonction ifarguments.length !== 2
. Ce modèle peut être répété un certain nombre de fois pour doter une variable de plusieurs définitions fonctionnelles différentes.la source
Je voudrais partager un exemple utile d'approche de type surchargé.
Utilisation: Clear (); // Efface tout le document
Clear (myDiv); // Efface le panneau référencé par myDiv
la source
JavaScript est un langage non typé, et je pense seulement que cela a du sens de surcharger une méthode / fonction en ce qui concerne le nombre de paramètres. Par conséquent, je recommanderais de vérifier si le paramètre a été défini:
la source
En juillet 2017, ce qui suit était la technique courante. Notez que nous pouvons également effectuer une vérification de type dans la fonction.
la source
Pour votre cas d'utilisation, voici comment je m'y attaquerais
ES6
(puisque c'est déjà la fin de 2017):Vous pouvez évidemment l'adapter pour qu'il fonctionne avec n'importe quelle quantité de paramètres et modifier simplement vos instructions conditionnelles en conséquence.
la source
il n'y a pas de surcharge réelle dans JS, de toute façon nous pouvons toujours simuler la surcharge de méthode de plusieurs façons:
méthode # 1: utiliser un objet
méthode # 2: utiliser les paramètres de repos (propagation)
méthode # 3: utilisez undefined
méthode # 4: vérification de type
la source
Bien que les paramètres par défaut ne surchargent pas, cela pourrait résoudre certains des problèmes auxquels les développeurs sont confrontés dans ce domaine. L'entrée est strictement décidée par la commande, vous ne pouvez pas réorganiser comme vous le souhaitez comme en surcharge classique:
Résultats en (pour l'année 2020):
Plus d'informations: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
la source
La première option mérite vraiment l'attention, car c'est la chose que j'ai trouvée dans la configuration de code assez complexe. Donc, ma réponse est
Avec un petit mais essentiel indice, les noms devraient être différents pour l'ordinateur, mais pas pour vous. Nommez des fonctions surchargées comme: func, func1, func2.
la source