¿Cuál es la mejor forma de falsificar la sobrecarga de funciones en Javascript?
Sé que no es posible sobrecargar funciones en Javascript como en otros idiomas. Si necesitaba una función con dos usos foo(x)
y foo(x,y,z)
cuál es la mejor / preferida forma:
- Usando diferentes nombres en primer lugar
- Usando argumentos opcionales como
y = y || 'default'
- Usando el número de argumentos
- Comprobación de tipos de argumentos
- ¿O como?
javascript
overloading
hamdiakoguz
fuente
fuente
Respuestas:
La mejor manera de sobrecargar funciones con parámetros es no verificar la longitud del argumento o los tipos; verificar los tipos solo hará que su código sea más lento y se divertirá con matrices, nulos, objetos, etc.
Lo que la mayoría de los desarrolladores hacen es agregar un objeto como último argumento para sus métodos. Este objeto puede contener cualquier cosa.
Luego puede manejarlo de la forma que desee en su método. [Interruptor, si no, etc.]
fuente
if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
arguments.length
no se recomienda la comprobación ? Además, he estado aquí antes y leí Lo que la mayoría de los desarrolladores hacen es ... , pero estoy seguro de que este es el único lugar que he visto hacer eso. ¡Ese método también estropea la azucaración sintáctica de tener 'sobrecargas'!A menudo hago esto:
C#:
JavaScript equivalente:
Este ejemplo particular es en realidad más elegante en javascript que C #. Los parámetros que no se especifican son 'indefinidos' en javascript, que se evalúa como falso en una declaración if. Sin embargo, la definición de la función no transmite la información de que p2 y p3 son opcionales. Si necesita mucha sobrecarga, jQuery ha decidido utilizar un objeto como parámetro, por ejemplo, jQuery.ajax (opciones). Estoy de acuerdo con ellos en que este es el enfoque más poderoso y claramente documentable para la sobrecarga, pero rara vez necesito más de uno o dos parámetros opcionales rápidos.
EDITAR: prueba IF modificada por sugerencia de Ian
fuente
undefined
en JS, nonull
. Como práctica recomendada, nunca debe configurar nadaundefined
, por lo que no debería ser un problema siempre y cuando cambie su pruebap2 === undefined
.false
como último argumento, no se concatenará"false"
hasta el final, porqueif(p3)
no se ramificará.typeof p2 === "undefined"
probablemente sea lo contrario de lo que espera en la instancia de su ejemplo, creo quetypeof p2 !== "undefined"
es lo que pretendía. Además, ¿puedo sugerir que se supone que concatena la cadena, el número y el booleano que realmente hacesp2 === "number"; p3 === "boolean"
===
y!==
? ¿Por qué no solo usar==
y!=
?No hay sobrecarga de funciones reales en JavaScript, ya que permite pasar cualquier número de parámetros de cualquier tipo. Debe verificar dentro de la función cuántos argumentos se han pasado y de qué tipo son.
fuente
La respuesta correcta es NO HAY SOBRECARGA EN JAVASCRIPT.
Comprobar / Cambiar dentro de la función no es SOBRECARGA.
El concepto de sobrecarga: en algunos lenguajes de programación, la sobrecarga de funciones o la sobrecarga de métodos es la capacidad de crear múltiples métodos del mismo nombre con diferentes implementaciones. Las llamadas a una función sobrecargada ejecutarán una implementación específica de esa función apropiada para el contexto de la llamada, permitiendo que una llamada de función realice diferentes tareas dependiendo del contexto.
Por ejemplo, doTask () y doTask (objeto O) son métodos sobrecargados. Para llamar a este último, se debe pasar un objeto como parámetro, mientras que el primero no requiere un parámetro y se llama con un campo de parámetro vacío. Un error común sería asignar un valor predeterminado al objeto en el segundo método, lo que resultaría en un error de llamada ambiguo, ya que el compilador no sabría cuál de los dos métodos usar.
https://en.wikipedia.org/wiki/Function_overloading
Todas las implementaciones sugeridas son geniales, pero a decir verdad, no existe una implementación nativa para JavaScript.
fuente
Hay dos formas de abordar esto mejor:
Pase un diccionario (matriz asociativa) si desea dejar mucha flexibilidad
Tome un objeto como argumento y use una herencia basada en prototipos para agregar flexibilidad.
fuente
Aquí hay un enfoque que permite la sobrecarga de métodos reales utilizando los tipos de parámetros, que se muestran a continuación:
Editar (2018) : desde que esto se escribió en 2011, la velocidad de las llamadas a métodos directos ha aumentado considerablemente, mientras que la velocidad de los métodos sobrecargados no.
No es un enfoque que recomendaría, pero vale la pena pensar en cómo puede resolver este tipo de problemas.
Aquí hay un punto de referencia de los diferentes enfoques: https://jsperf.com/function-overloading . Muestra que la sobrecarga de funciones (teniendo en cuenta los tipos) puede ser aproximadamente 13 veces más lenta en el V8 de Google Chrome a partir de 16.0 (beta) .
Además de pasar un objeto (es decir
{x: 0, y: 0}
), también se puede adoptar el enfoque C cuando sea apropiado, nombrando los métodos en consecuencia. Por ejemplo, Vector.AddVector (vector), Vector.AddIntegers (x, y, z, ...) y Vector.AddArray (integerArray). Puede mirar las bibliotecas C, como OpenGL para nombrar la inspiración.Editar : agregué un punto de referencia para pasar un objeto y probarlo usando ambos
'param' in arg
yarg.hasOwnProperty('param')
, y la sobrecarga de funciones es mucho más rápida que pasar un objeto y verificar las propiedades (al menos en este punto de referencia).Desde una perspectiva de diseño, la sobrecarga de funciones solo es válida o lógica si los parámetros sobrecargados corresponden a la misma acción. Por lo tanto, es lógico pensar que debería haber un método subyacente que solo se ocupe de detalles específicos, de lo contrario, eso podría indicar elecciones de diseño inapropiadas. Por lo tanto, también se podría resolver el uso de la sobrecarga de funciones mediante la conversión de datos a un objeto respectivo. Por supuesto, uno debe considerar el alcance del problema, ya que no es necesario hacer diseños elaborados si su intención es solo imprimir un nombre, pero para el diseño de marcos y bibliotecas tal pensamiento está justificado.
Mi ejemplo proviene de una implementación de Rectángulo, de ahí la mención de Dimensión y Punto. Tal vez rectángulo podría añadir un
GetRectangle()
método para elDimension
yPoint
prototipo, y luego la sobrecarga de funciones problema se solucionó. ¿Y qué hay de los primitivos? Bueno, tenemos una longitud de argumento, que ahora es una prueba válida ya que los objetos tienen unGetRectangle()
método.fuente
La mejor manera realmente depende de la función y los argumentos. Cada una de sus opciones es una buena idea en diferentes situaciones. Generalmente intento estos en el siguiente orden hasta que uno de ellos funciona:
Usando argumentos opcionales como y = y || 'defecto'. Esto es conveniente si puede hacerlo, pero puede que no siempre funcione prácticamente, por ejemplo, cuando 0 / nulo / indefinido sería un argumento válido.
Usando el número de argumentos. Similar a la última opción, pero puede funcionar cuando el # 1 no funciona.
Comprobación de tipos de argumentos. Esto puede funcionar en algunos casos donde el número de argumentos es el mismo. Si no puede determinar los tipos de manera confiable, es posible que deba usar nombres diferentes.
Usando diferentes nombres en primer lugar. Es posible que deba hacer esto si las otras opciones no funcionan, no son prácticas o si son coherentes con otras funciones relacionadas.
fuente
El problema es que JavaScript NO admite de forma nativa la sobrecarga de métodos. Entonces, si ve / analiza dos o más funciones con los mismos nombres, solo considerará la última función definida y sobrescribirá las anteriores.
Una de las formas en que creo que es adecuada para la mayoría de los casos es la siguiente:
Digamos que tienes un método
En lugar de sobrecargar el método que no es posible en JavaScript , puede definir un nuevo método
y luego modifique la primera función de la siguiente manera:
Si tiene muchos de estos métodos sobrecargados, considere usar
switch
soloif-else
declaraciones.( más detalles )
PD: el enlace de arriba va a mi blog personal que tiene detalles adicionales.
fuente
No estoy seguro de las mejores prácticas, pero así es como lo hago:
fuente
Acabo de probar esto, tal vez se adapte a tus necesidades. Dependiendo del número de argumentos, puede acceder a una función diferente. Lo inicializa la primera vez que lo llama. Y el mapa de funciones está oculto en el cierre.
Pruébalo.
fuente
Dado que JavaScript no tiene funciones, el objeto de opciones de sobrecarga se puede usar en su lugar. Si hay uno o dos argumentos requeridos, es mejor mantenerlos separados del objeto de opciones. Aquí hay un ejemplo sobre cómo usar el objeto de opciones y los valores poblados al valor predeterminado en caso de que el valor no se haya pasado en el objeto de opciones.
Aquí hay un ejemplo sobre cómo usar el objeto de opciones
fuente
No hay forma de funcionar con sobrecarga en javascript. Entonces, recomiendo lo siguiente por
typeof()
método en lugar de función múltiple para falsificar la sobrecarga.¡Buena suerte!
fuente
var type = typeof param; if (type === 'string') ...
INTRODUCCIÓN
Hasta ahora, leer tantas respuestas le daría dolor de cabeza a cualquiera. Cualquiera que intente conocer el concepto necesitaría conocer los siguientes requisitos previos .
Function overloading Definition
`Function Length property
`Function argument property
Function overloading
en su forma más simple significa que una función realiza diferentes tareas en función del número de argumentos que se le pasan. En particular, TASK1, TASK2 y TASK3 se destacan a continuación y se realizan en función del número de pasesarguments
a la misma funciónfooYo
.NOTA : JS no proporciona la capacidad incorporada de sobrecarga de funciones.
Alternativa
John E Resig (creador de JS) ha señalado una alternativa que utiliza los requisitos previos anteriores para lograr la capacidad de implementar la sobrecarga de funciones.
El siguiente código utiliza un enfoque sencillo pero ingenuo mediante el uso de
if-else
oswitch
declaración.argument-length
propiedad.Otra técnica es mucho más limpia y dinámica. Lo más destacado de esta técnica es la
addMethod
función genérica.definimos una función
addMethod
que se usa para agregar diferentes funciones a un objeto con el mismo nombre pero con diferentes funcionalidades .debajo de la
addMethod
función acepta el nombre del objeto de tres parámetrosobject
, el nombre dename
la función y la función que queremos que se invoquefn
.addMethod
definición internavar old
almacena la referencia a lo anteriorfunction
almacenado con la ayuda del cierre, una burbuja protectora.addMethod
agrega tres funciones que, cuando se invoca, se utilizaninja.whatever(x)
con el número de argumentosx
que pueden ser cualquier cosa, es decir, en blanco o una o más de una, invoca diferentes funciones como se define al hacer uso de laaddMethod
función.fuente
Otra forma de abordar esto es mediante el uso de la variable especial: argumentos , esta es una implementación:
para que pueda modificar este código para:
fuente
mira esto. Esta muy padre. http://ejohn.org/blog/javascript-method-overloading/ Trick Javascript para permitirle hacer llamadas como esta:
fuente
Func(new Point())
yFunc(new Rectangle())
ejecutaré diferentes funciones. Pero debo señalar que este es un truco sucio, ya que la sobrecarga de métodos es realmente una tarea de tiempo de compilación, no de tiempo de ejecución.Sobrecarga de funciones en Javascript:
La sobrecarga de funciones es la capacidad de un lenguaje de programación para crear múltiples funciones del mismo nombre con diferentes implementaciones. cuando se llama a una función sobrecargada, ejecutará una implementación específica de esa función apropiada para el contexto de la llamada. Este contexto suele ser la cantidad de argumentos recibidos, y permite que una llamada de función se comporte de manera diferente según el contexto.
Javascript no tiene una función de sobrecarga incorporada. Sin embargo, este comportamiento se puede emular de muchas maneras. Aquí hay una conveniente simple:
En escenarios en los que no sabes cuántos argumentos obtendrás, puedes usar el operador rest, que son tres puntos
...
. Convertirá el resto de los argumentos en una matriz. Sin embargo, tenga cuidado con la compatibilidad del navegador. Aquí hay un ejemplo:fuente
Como esta publicación ya contiene muchas soluciones diferentes, pensé que publicaría otra.
esto se puede usar como se muestra a continuación:
Esta solución no es perfecta, pero solo quiero demostrar cómo se puede hacer.
fuente
Puede usar el 'addMethod' de John Resig. Con este método puede "sobrecargar" los métodos basados en el recuento de argumentos.
También he creado una alternativa a este método que utiliza el almacenamiento en caché para contener las variaciones de la función. Aquí se describen las diferencias.
fuente
Patrón de reenvío => la mejor práctica en sobrecarga de JS
Reenviar a otra función cuyo nombre se construye a partir de los puntos tercero y cuarto:
Solicitud en su caso:
Otra muestra compleja:
fuente
Sobrecarga de funciones mediante polimorfismo dinámico en 100 líneas de JS
Esto es de un cuerpo más grande de código que incluye los
isFn
,isArr
, etc. funciones comprobación de tipos. La versión de VanillaJS a continuación ha sido modificada para eliminar todas las dependencias externas, sin embargo, tendrá que definir sus propias funciones de verificación de tipo para usar en las.add()
llamadas.Nota: Esta es una función de ejecución automática (por lo que podemos tener un alcance cerrado / cerrado), de ahí la asignación a
window.overload
más que afunction overload() {...}
.Uso:
La persona que llama define sus funciones sobrecargadas asignando una variable al retorno de
overload()
. Gracias al encadenamiento, las sobrecargas adicionales se pueden definir en serie:El argumento opcional único para
overload()
definir la función "predeterminada" para llamar si no se puede identificar la firma. Los argumentos para.add()
son:fn
:function
definición de la sobrecarga;a_vArgumentTests
:Array
defunction
s definiendo las pruebas a ejecutar en elarguments
. Cada unofunction
acepta un único argumento y devuelvetrue
tu en función de si el argumento es válido;sAlias
(Opcional):string
definir el alias para acceder directamente a la función de sobrecarga (fn
), por ejemplomyOverloadedFn.noArgs()
, llamará a esa función directamente, evitando las pruebas de polimorfismo dinámico de los argumentos.Esta implementación en realidad permite más que solo sobrecargas de funciones tradicionales como el segundo
a_vArgumentTests
argumento para.add()
definir en la práctica tipos personalizados. Por lo tanto, ¡podría abrir argumentos no solo en función del tipo, sino también de rangos, valores o colecciones de valores!Si mira a través de las 145 líneas de código
overload()
, verá que cada firma se clasifica por el número dearguments
pasadas. Esto se hace para limitar el número de pruebas que estamos ejecutando. También llevo un registro del recuento de llamadas. Con algún código adicional, las matrices de funciones sobrecargadas podrían reorganizarse para que las funciones más comúnmente llamadas se prueben primero, agregando nuevamente alguna medida de mejora del rendimiento.Ahora, hay algunas advertencias ... Como Javascript está mal escrito, tendrá que tener cuidado con su,
vArgumentTests
ya queinteger
podría validarse comofloat
, etc.Versión JSCompress.com (1114 bytes, 744 bytes g-zipped):
fuente
Ahora puede hacer una sobrecarga de funciones en ECMAScript 2018 sin polyfills, verificar la longitud / tipo de var, etc., solo use la sintaxis de propagación .
¿Qué es la sintaxis extendida?
Nota: la sintaxis extendida en literales de objetos no funciona en Edge e IE y es una característica experimental. ver compatibilidad del navegador
fuente
Algo como esto se puede hacer para la sobrecarga de funciones.
Fuente
fuente
Esta es una pregunta antigua, pero creo que necesita otra entrada (aunque dudo que alguien la lea). El uso de Expresiones de funciones invocadas inmediatamente (IIFE) se puede usar junto con cierres y funciones en línea para permitir la sobrecarga de funciones. Considere el siguiente ejemplo (artificial):
En resumen, el uso del IIFE crea un ámbito local, lo que nos permite definir la variable privada
old
para almacenar una referencia a la definición inicial de la funciónfoo
. Esta función devuelve una función en líneanewFoo
que registra el contenido de ambos dos argumentos si se pasa exactamente dos argumentosa
yb
o llama a laold
función siarguments.length !== 2
. Este patrón se puede repetir cualquier cantidad de veces para dotar a una variable con varias definiciones funcionales diferentes.fuente
Me gustaría compartir un ejemplo útil de un enfoque sobrecargado.
Uso: Claro (); // borra todo el documento
Claro (myDiv); // Borra el panel al que hace referencia myDiv
fuente
JavaScript es un lenguaje sin tipo, y solo creo que tiene sentido sobrecargar un método / función con respecto al número de parámetros. Por lo tanto, recomendaría verificar si el parámetro ha sido definido:
fuente
A partir de julio de 2017, la siguiente ha sido la técnica común. Tenga en cuenta que también podemos realizar verificaciones de tipo dentro de la función.
fuente
Para su caso de uso, así es como lo abordaría
ES6
(ya que es a finales de 2017):Obviamente, puede adaptar esto para trabajar con cualquier cantidad de parámetros y simplemente cambiar sus declaraciones condicionales en consecuencia.
fuente
no hay sobrecarga real en JS, de todos modos todavía podemos simular la sobrecarga de métodos de varias maneras:
método # 1: usar objeto
método # 2: use los parámetros rest (spread)
método # 3: uso indefinido
método # 4: verificación de tipo
fuente
Si bien los parámetros predeterminados no se están sobrecargando, podrían resolver algunos de los problemas que enfrentan los desarrolladores en esta área. La entrada está estrictamente decidida por el pedido, no puede reordenar como desee como en la sobrecarga clásica:
Resultados en (para el año 2020):
Más información: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
fuente
La primera opción realmente merece atención porque es lo que he encontrado en una configuración de código bastante compleja. Entonces mi respuesta es
Con una pequeña pero esencial pista, los nombres deberían ser diferentes para la computadora, pero no para ti. Nombre funciones sobrecargadas como: func, func1, func2.
fuente