Surcharge de fonctions en Javascript - les Meilleures pratiques
Quel est le meilleur moyen(s) de faux surcharge de fonctions en Javascript?
Je sais qu'il n'est pas possible de surcharger des fonctions en Javascript comme dans d'autres langues.
Si j'ai besoin d'une fonction à deux utilisations foo(x)
et foo(x,y,z)
qui est le meilleur /le moyen privilégié:
- En utilisant des noms différents, en premier lieu,
- En utilisant des arguments optionnels comme
y = y || 'default'
- En utilisant le nombre d'arguments
- La vérification des types d'arguments
- Ou comment?
- Il serait peut-être utile de se demander pourquoi vous pensez que vous avez besoin de surcharge de fonctions pour commencer. Je pense que nous permettra de nous rapprocher d'une solution réelle.
- C'est fermé, mais je ne les suivants: cette.sélectionner = { exemple: selectByInstance, // la Fonction du texte: selectByText, // valeur de la Fonction: selectByValue // Fonction };
- Ma réponse montre comment faire moment de l'exécution de la fonction de surcharge, il a une vitesse de peine et je ne le conseille pas de le faire pour l'obtenir autour de Javascript du cahier des charges. La fonction de surcharge est vraiment un moment de la compilation de la tâche, j'ai seulement fournir la réponse à des fins d'enseignement et de laisser à votre propre discrétion quant à savoir si ou de ne pas l'utiliser dans le code.
- Juste au cas où il est utile, j'ai construit un léger js cadre qui permet en fonction de leur type surcharge de la méthode. Évidemment, les mêmes restrictions s'appliquent en ce qui concerne les performances, mais il a bien fonctionné pour moi jusqu'à présent et a encore beaucoup de place à l'amélioration: blog.pebbl.co.royaume-uni/2013/01/describejs.html#methodoverloading
Vous devez vous connecter pour publier un commentaire.
La meilleure façon de faire de la surcharge de fonctions avec des paramètres n'est pas de vérifier l'argument de la longueur ou le type; vérification de la des types va juste faire votre code lent et vous avez le plaisir de Tableaux, les valeurs null, Objets, etc.
Ce que la plupart des développeurs de faire est de virer de bord sur un objet comme le dernier argument à leurs méthodes. Cet objet peut contenir quoi que ce soit.
Alors vous pouvez le manipuler de toute façon que vous voulez dans votre méthode. [Switch, if-else, etc.]
if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
arguments.length
n'est pas recommandé? Aussi, j'ai été ici avant et de lire Ce que la plupart des développeurs n'est..., mais je suis sûr que c'est le seul endroit que j'ai vu que cela se fasse. Cette méthode gâte aussi les syntaxiques sugaryness de "surcharges'!arguments.length
est une mauvaise solution, c'est juste que dans certains cas, vous devrez revenir à la vérification de types (qui n'est pas idéal). Gotcha!var thing_handlers={ string : function(x){ return x;}, number : function(x) {return x+25; } }; function do_thing(x) {return thing_handlers[typeof x](x);}
c'est à la fois rapide, polymorphe, et le plus important, se bloque lors de l'exécution de forcer les développeurs à écrire coffre-fort(r) du code.Je fais souvent ce:
C#:
JavaScript Équivalent:
Cet exemple particulier est en fait plus élégant en javascript qu'en C#. Les paramètres qui ne sont pas spécifiés sont 'undefined' en javascript, qui évalue à false dans une instruction if. Cependant, la définition de la fonction ne pas transmettre les informations que p2 et p3 sont facultatifs. Si vous avez besoin d'un lot de surcharge, jQuery a décidé d'utiliser un objet en tant que paramètre, par exemple, jQuery.ajax(options). Je suis d'accord avec eux que c'est le plus puissant et clairement consignées approche de la surcharge, mais j'ai rarement besoin de plus d'un ou deux paramètres facultatifs.
EDIT: changé SI test par Ian suggestion
undefined
en JS, pasnull
. Comme une meilleure pratique, vous ne devriez jamais mettre quoi que ce soit àundefined
, de sorte qu'il ne devrait pas être un problème tant que vous modifiez votre test dep2 === undefined
.false
comme le dernier argument, alors il ne sera pas concaténer"false"
à la fin, parce que laif(p3)
ne branche.typeof p2 === "undefined"
typeof p2 === "undefined"
est probablement l'inverse de ce qui vous attend dans le cas de ton exemple, je pense quetypeof p2 !== "undefined"
est ce que vous avez prévu. Aussi, je vous propose d'être son soi-disant pour concaténer des chaînes, le numéro et la valeur de type boolean qui vous fait fairep2 === "number"; p3 === "boolean"
p2 !== void 0
pour un moins verbeux comparaison===
et!==
? Pourquoi ne pas simplement utiliser==
et!=
?Il n'y a pas de véritable surcharge de fonctions en JavaScript car il vous permet de passer n'importe quel nombre de paramètres de n'importe quel type. Vous devez vérifier à l'intérieur de la fonction de combien de arguments ont été adoptées et de quel type ils sont.
La réponse correcte est " IL n'y a PAS de SURCHARGE EN JAVASCRIPT.
Contrôle /de Commutation à l'intérieur de la fonction n'est pas de SURCHARGE.
Le concept de surcharge:
Dans certains langages de programmation, la fonction de surcharge ou surcharge de la méthode est la possibilité de créer plusieurs méthodes de même nom avec différentes implémentations. Les appels à une fonction surchargée sera exécuté une mise en œuvre spécifique de la fonction appropriée au contexte de l'appel, permettant à un appel de fonction pour effectuer des tâches différentes selon le contexte.
Par exemple, doTask() et doTask(object O) sont des méthodes surchargées. À l'appel de ce dernier, un objet doit être passé en paramètre, alors que le premier n'a pas besoin d'un paramètre, et est appelée avec un paramètre vide le champ. Une erreur commune serait d'attribuer une valeur par défaut à l'objet dans la deuxième méthode, qui serait la conséquence de l'ambiguïté d'un appel d'erreur, car le compilateur ne sais pas laquelle des deux méthodes à utiliser.
https://en.wikipedia.org/wiki/Function_overloading
Toutes les propositions de mise en œuvre est grande, mais la vérité d'être dit, il n'est pas natif de la mise en œuvre de JavaScript.
Il y a deux façons dont vous pourriez aborder cette mieux:
Passer d'un dictionnaire (tableau associatif) si vous voulez laisser un peu de souplesse
Prendre un objet en argument et de l'utilisation du prototype à base d'héritage pour ajouter de la flexibilité.
Ici est une approche qui permet une véritable surcharge de la méthode à l'aide de types de paramètres, illustré ci-dessous:
Modifier (2018): Depuis que ceci a été écrit en 2011, la vitesse de la méthode directe, les appels a considérablement augmenté, tandis que la vitesse de surcharge de méthodes n'ont pas.
Il n'est pas une approche que je recommande, mais c'est un bon exercice de la pensée à penser à comment vous pouvez résoudre ces types de problèmes.
Voici un benchmark des différentes approches - https://jsperf.com/function-overloading. Il montre que la fonction de surcharge (en prenant les types de compte) peut être autour de 13 fois plus lent dans Google Chrome V8 de 16.0(bêta).
Ainsi que le passage d'un objet (c'est à dire
{x: 0, y: 0}
), on peut aussi prendre le C approche cas échéant, de nommer les méthodes en conséquence. Par exemple, le Vecteur.AddVector(vecteur), Vecteur.AddIntegers(x, y, z, ...) et de Vecteur.AddArray(integerArray). Vous pouvez regarder les bibliothèques C, telles que OpenGL pour le nommage de l'inspiration.Modifier: j'ai ajouté une référence pour le passage d'un objet et d'essais pour l'objet à l'aide de deux
'param' in arg
etarg.hasOwnProperty('param')
, et la fonction de surcharge est beaucoup plus rapide que de passer un objet et la vérification de propriétés (dans ce cas-test au moins).À partir d'une conception de point de vue, la fonction de surcharge n'est valable que logique ou si la surcharge des paramètres correspondent à la même action. Il va de soi qu'il doit y avoir un sous-jacente méthode qui n'est concerné avec des détails précis, sinon ça peut indiquer inapproprié des choix de conception. Donc, on pourrait également résoudre l'utilisation de la surcharge de fonction par la conversion des données à l'objet concerné. Bien sûr, il faut tenir compte de l'étendue du problème comme il n'y a pas besoin d'en faire des dessins si votre intention est simplement d'imprimer un nom, mais pour la conception de cadres et de bibliothèques telles pensée est justifiée.
Mon exemple est tiré d'un Rectangle de mise en œuvre - d'où la mention de la Dimension et de Point de. Peut-être Rectangle pourrait ajouter un
GetRectangle()
méthode à laDimension
etPoint
prototype, et ensuite la fonction de surcharge question est triée. Et que dire de primitives? Eh bien, nous avons argument de la longueur, qui est maintenant un test valide puisque les objets ont uneGetRectangle()
méthode.La meilleure façon vraiment dépend de la fonction et les arguments. Chacun de vos options est une bonne idée dans différentes situations. J'essaye généralement dans l'ordre suivant, jusqu'à ce que l'un d'entre eux fonctionne:
En utilisant des arguments optionnels de la forme y = y | | "par défaut". Cela est pratique si vous pouvez le faire, mais il peut ne pas toujours fonctionner dans la pratique, par exemple lorsque 0/null/indéfini serait un argument valable.
En utilisant le nombre d'arguments. Similaire à la dernière option, mais peut fonctionner lorsque #1 ne fonctionne pas.
La vérification des types d'arguments. Cela peut fonctionner dans certains cas où le nombre d'arguments est la même. Si vous ne pouvez pas déterminer de manière fiable les types, vous pouvez avoir besoin d'utiliser des noms différents.
En utilisant des noms différents en premier lieu. Vous pouvez avoir besoin de faire cela si les autres options ne fonctionne pas, ne sont pas pratiques, ou pour des raisons de cohérence avec d'autres fonctions connexes.
Le problème est que le JavaScript ne supporte PAS la surcharge de méthode. Donc, si il voit/analyse de deux ou plus de fonctions pour un même nom il va il suffit de considérer la dernière fonction définie et remplace les précédentes.
Un de la manière, je pense, est approprié pour la plupart des cas est la suivante -
Permet de dire 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 de modifier la 1ère fonction comme suit -
Si vous avez plusieurs de ces méthodes surchargées envisager d'utiliser
switch
que justeif-else
consolidés.(plus de détails)
PS: le lien ci-Dessus va sur mon blog personnel qui a plus de détails.
Je ne suis pas sûr à propos de les meilleures pratiques, mais voici comment je le fais:
J'ai juste essayé ce, peut-être qu'il s'adapte à vos besoins.
Selon le nombre d'arguments, vous pouvez accéder à une fonction différente. Si vous initialisez la première fois que vous l'appelez.
Et la fonction map est caché dans la fermeture.
Le tester.
Depuis JavaScript n'a pas de fonction de surcharge objet d'options peut être utilisé à la place. Si 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 les options de l'objet et peuplé de valeurs valeur par défaut dans le cas où si la valeur n'a pas été adopté dans les options de l'objet.
ici est un exemple sur la façon d'utiliser les options de l'objet
Il n'y a aucun moyen de surcharge de fonctions en javascript.
Donc, je recommande comme suit par
typeof()
méthode au lieu dela fonction multiple de faux surcharge.
Bonne chance!
var type = typeof param; if (type === 'string') ...
INTRODUCTION
Mesure de la lecture à travers si de nombreuses réponses donnerait à n'importe qui mal à la tête. Toute personne essayant de connaître le concept serait nécessaire de connaître le condition suivantes.
Function overloading Definition
,Function Length property
,Function argument property
Function overloading
dans sa forme la plus simple signifie qu'une fonction effectue différentes tâches sur la base du nombre d'arguments qui sont passés à l'. Notamment la TASK1, TASK2 et TASK3 sont mis en évidence ci-dessous et sont exécutées sur la base du nombre dearguments
d'être passée à la même fonctionfooYo
.NOTE
- JS ne fournit pas de fonction intégrée de capacité de surcharge de fonctions.
Alternative
John E Resig (créateur de la JS) a signalé une alternative qui utilise les conditions préalables ci-dessus pour atteindre la capacité de mettre en œuvre la fonction de surcharge.
Le code ci-dessous utilise une simple, mais approche naïve en utilisant
if-else
ouswitch
déclaration.argument-length
propriété.JS:
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 des fonctions différentes à un objet avec la même nom mais différentes fonctionnalités.ci-dessous la
addMethod
fonction accepte trois paramètres nom de l'objetobject
, le nom de la fonctionname
et de la fonction que nous voulons être invoquéefn
.addMethod
définitionvar old
stocke la référence à la précédentefunction
être stockées par l'aide de la fermeture - une bulle protectrice.JS:
addMethod
ajoute trois fonctions qui, lorsqu'il est appelé à l'aideninja.whatever(x)
avec le nombre d'argumentsx
qui peut être n'importe quoi, c'est à dire soit vide ou d'un ou de plus d'une invoque différentes fonctions telles que définies lors de l'utilisation duaddMethod
fonction.JS:
Une autre approche consiste à utiliser la variable spéciale: arguments, c'est une mise en œuvre:
de sorte que vous pouvez modifier ce code pour:
vérifier cela. Il est très cool.
http://ejohn.org/blog/javascript-method-overloading/
Astuce Javascript pour vous permettre de faire des appels comme ceci:
Func(new Point())
etFunc(new Rectangle())
va exécuter les différentes fonctions. Mais je dois souligner que c'est un sale hack, car la surcharge de méthode est vraiment un moment de la compilation, tâche de ne pas courir de temps.Que ce post contient déjà un grand nombre de différentes solutions que j'ai pensé que je poste un autre.
ceci peut être utilisé comme indiqué ci-dessous:
Cette solution n'est pas parfaite, mais je veux seulement vous montrer comment il pourrait en être fait.
Vous pouvez l'utilisateur le "addMethod" de John Resig. Avec cette méthode, vous pouvez la "surcharge" des méthodes basées sur des arguments de comptage.
J'ai également créé une alternative à cette méthode qui utilise la mise en cache de tenir les variations de la fonction. Les différences sont décrites ici
Transfert Pattern => la meilleure pratique sur JS surcharge
Transférer à une autre fonction dont le nom est construit à partir de la 3e & 4ème points :
Application sur votre cas :
Autres Échantillons Complexes :
De Surcharge de fonctions via la Dynamique du Polymorphisme de 100 lignes de JS
C'est à partir d'un grand corps de code qui comprend la
isFn
,isArr
, etc. vérification du type de fonctions. Le VanillaJS version ci-dessous a été retravaillé afin d'en retirer toutes les dépendances externes, cependant, vous aurez à définir vous êtes propre vérification du type de fonctions à utiliser dans les.add()
appels.Remarque: C'est une auto-exécution de la fonction (on peut donc avoir une fermeture/closed de la portée), d'où l'affectation à
window.overload
plutôt quefunction overload() {...}
.Utilisation:
L'appelant définit leurs fonctions surchargées par l'affectation d'une variable pour le retour de
overload()
. Grâce à l'enchaînement, les surcharges supplémentaires peuvent être définis dans les séries:Le seul argument optionnel de
overload()
définit le "défaut" de la fonction à appeler si la signature ne peut pas être identifié. Les arguments de.add()
sont:fn
:function
la définition de la surcharge;a_vArgumentTests
:Array
defunction
s définir les tests à exécuter sur learguments
. Chaquefunction
accepte un seul argument et renvoietrue
ton en fonction de si l'argument est valide;sAlias
(Facultatif):string
la définition de l'alias pour accéder directement à la fonction de surcharge (fn
), par exemplemyOverloadedFn.noArgs()
va appeler la fonction directement, en évitant la dynamique polymorphisme tests des arguments.Cette mise en œuvre permet en fait pour plus que juste la fonction traditionnelle des surcharges en tant que deuxième
a_vArgumentTests
argument.add()
dans la pratique définit les types personnalisés. Ainsi, vous pourriez porte arguments ne sont pas seulement fondées sur le type, mais sur des plages, des valeurs ou des collections de valeurs!Si vous regardez dans les 145 lignes de code pour
overload()
vous verrez que chaque signature est classé par le nombre dearguments
passé. Ceci est fait de sorte que nous sommes en limitant le nombre de tests que nous avons sont en cours d'exécution. Je garde aussi la trace d'un nombre d'appels. Avec un code supplémentaire, les tableaux de surcharge de fonctions pourrait être re-triés de façon plus communément appelées les fonctions sont testés en premier, de nouveau en ajoutant une certaine mesure, de l'amélioration de la performance.Maintenant, il ya quelques mises en garde... Que Javascript est faiblement typé, vous devez être prudent avec votre
vArgumentTests
comme uninteger
pourrait être validé comme unfloat
, etc.JSCompress.com version (1114 octets, 744 octets g-zip):
Vous pouvez maintenant faire la fonction de surcharge en ECMAScript 2018 sans polyfills, la vérification var longueur/type, etc., suffit d'utiliser la la propagation de la syntaxe.
JS:
Ce qui est de la propagation de la syntaxe?
Remarque: la propagation de la syntaxe dans les littéraux d'objet n'a pas de travail à Bord et IE et c'est une fonctionnalité expérimentale. voir le navigateur de compatibilité
La première option qui mérite vraiment l'attention, parce que c'est la chose que j'ai grandi dans très complexe de code de configuration. Donc, ma réponse est
Avec un peu, mais essentielles, de conseil, de noms différents pour ordinateur, mais pas pour vous. Nom de la surcharge des fonctions comme: func, func1, func2.
C'est une vieille question, mais qui, je pense, besoin d'une autre entrée (même si je doute que quelqu'un va le lire). L'utilisation de Immédiatement appelé les Expressions de Fonction (IIFE) peut être utilisé en conjonction avec les fermetures et les fonctions inline pour permettre à la fonction de surcharge. Considérez les points suivants (fictive) exemple:
En bref, l'utilisation de la IIFE 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 retourne alors une fonction inlinenewFoo
qui enregistre le contenu de deux arguments si il est passé exactement deux argumentsa
etb
ou appelle laold
fonction siarguments.length !== 2
. Ce motif peut être répété un nombre quelconque de fois de doter d'une variable avec plusieurs fonctionnel defitions.JavaScript est le langage non typé, et je ne pense que cela a du sens pour surcharger une méthode/fonction en ce qui concerne le nombre de paramètres. Par conséquent, je vous recommande de vérifier si le paramètre a été défini:
En juillet 2017, la suivante a été la technique courante. Notez que nous pouvons également effectuer une vérification de type à l'intérieur de la fonction.
Pour votre cas d'utilisation, c'est comment je pourrais l'aborder avec
ES6
(puisque c'est déjà la fin de 2017):Vous pouvez évidemment adapter cela fonctionne avec n'importe quel nombre de paramètres et il suffit de changer vos instructions conditionnelles en conséquence.
Quelque chose comme ceci peut être fait pour de surcharge de fonctions.
Source
Nous avons fait over.js de résoudre ce problème est un moyen très élégant. Vous pouvez le faire:
Donc j'ai vraiment aimé cette façon de faire les choses que j'ai trouvé dans les secrets de la javascript ninja
vous utilisez ensuite addMethod pour ajouter des fonctions surchargées à n'importe quel objet. La principale confusion dans le présent code a été pour moi l'utilisation de la fn.longueur == arguments.longueur -- cela fonctionne parce que le fn.la longueur est le nombre de paramètres, bien que les arguments.la longueur est le nombre de paramètres que l'on appelle en fait avec la fonction. La raison de la fonction anonyme, n'a pas d'argument est parce que vous pouvez passer à n'importe quel nombre d'arguments en javascript et de la langue est indulgent.
Je l'ai aimé parce que vous pouvez l'utiliser partout: il suffit de créer cette fonction et utilisez simplement la méthode quelle que soit la base de code que vous voulez.
Il permet aussi d'éviter d'avoir un trop grand si/switch, qui devient difficile à lire si vous commencez à écrire de code complexe (la accepté de répondre à entraînera dans cette).
En termes d'inconvénients, je suppose que le code est d'abord un peu obscur...mais je ne suis pas sûr que d'autres?
Je voudrais partager un bon exemple de surcharge de démarche.
Utilisation:
Clear(); //Efface tous les document
Clair(myDiv); //Efface le panneau référencé par myDiv
J'aime @AntouanK de l'approche. Je me retrouve souvent à offrir une fonction avec un nombre variable o les paramètres et les différents types. Parfois, ils ne suivent pas un ordre. J'utilise à la carte à la recherche des types de paramètres:
J'ai été en utilisant cette fonction pour embellir mon surcharges pour les années:
Affiche:
Prendre un coup d'oeil à jQuery
off
méthode:De nombreuses fonctions surchargées quand optimisé pour les performances sont quasiment illisibles. Vous devez déchiffrer la tête de la fonction. C'est peut-être plus rapide que l'utilisation d'un
overload
fonction comme je le fournir; cependant, elle est plus lente à partir d'un point de vue humain à l'égard de l'identification de ce qui surcharge a été appelé.il n'y a pas de surcharge en JS, de toute façon on peut toujours simuler la surcharge de méthode, de plusieurs façons:
méthode #1:
utiliser l'objet
méthode #2:
repos (spread) paramètres
méthode #3:
utilisation non défini
méthode n ° 4:
vérification de type
De surcharge de fonctions en Javascript:
De surcharge de fonctions est la capacité d'un langage de programmation pour créer plusieurs fonctions de même nom avec différentes implémentations. lorsqu'une surcharge de la fonction est appelée, elle va exécuter une fonction spécifique de la mise en œuvre de cette fonction appropriée au contexte de l'appel. Ce contexte est généralement le nombre d'arguments est reçoit, et il permet à un seul appel de fonction pour se comporter différemment selon le contexte.
Javascript n'est pas ont construit en fonction de la surcharge. Cependant, ce comportement peut être imité dans de nombreuses façons. Ici est une pratique simple:
JS:
Dans les scénarios où vous ne savez pas combien d'arguments que vous allez obtenir, vous pouvez utiliser le reste de l'opérateur qui est de trois points
...
. Il vous permet de convertir le reste des arguments dans un tableau. Méfiez-vous de navigateur de compatibilité si. Voici un exemple:JS:
Je suis en train de travailler sur une bibliothèque qui fournit la classe comme des fonctionnalités de code Javascript, actuellement, il prend en charge les constructeurs, l'héritage, les méthodes de surcharge par le nombre de paramètres et par types de paramètres, mixin, la statique de propriétés et de singleton.
Voir un exemple de surcharge de la méthode à l'aide de la bibliothèque:
Des commentaires, des corrections de bug, de la documentation et des tests améliore sont les bienvenus!
https://github.com/eutsiv/eutsiv.js