Enfoque clásico (no js) de sobrecarga:
function myFunc(){
//code
}
function myFunc(overloaded){
//other code
}
Javascript no permitirá que se defina más de una función con el mismo nombre. Como tal, aparecen cosas como esta:
function myFunc(options){
if(options["overloaded"]){
//code
}
}
¿Existe una mejor solución para la sobrecarga de funciones en javascript que no sea pasar un objeto con las sobrecargas en él?
Pasar sobrecargas puede hacer que una función se vuelva demasiado detallada porque cada posible sobrecarga necesitaría una declaración condicional. El uso de funciones para lograr el //code
interior de esas declaraciones condicionales puede causar situaciones complicadas con ámbitos.
javascript
Travis J
fuente
fuente
Respuestas:
Hay varios aspectos de la sobrecarga de argumentos en Javascript:
Argumentos variables : puede pasar diferentes conjuntos de argumentos (tanto en tipo como en cantidad) y la función se comportará de una manera que coincida con los argumentos que se le pasen.
Argumentos predeterminados : puede definir un valor predeterminado para un argumento si no se pasa.
Argumentos con nombre : el orden de los argumentos se vuelve irrelevante y usted simplemente nombra los argumentos que desea pasar a la función.
A continuación se muestra una sección sobre cada una de estas categorías de manejo de argumentos.
Argumentos variables
Debido a que javascript no tiene verificación de tipo en los argumentos o la cantidad requerida de argumentos, solo puede tener una implementación
myFunc()
que se adapte a los argumentos que se le pasaron al verificar el tipo, la presencia o la cantidad de argumentos.jQuery hace esto todo el tiempo. Puede hacer que algunos de los argumentos sean opcionales o puede ramificar su función dependiendo de qué argumentos se le pasen.
Al implementar estos tipos de sobrecargas, tiene varias técnicas diferentes que puede utilizar:
undefined
.arguments.length
.arguments
pseudoarreglo para acceder a cualquier argumento dado conarguments[i]
.Aquí hay unos ejemplos:
Veamos el
obj.data()
método de jQuery . Admite cuatro formas diferentes de uso:Cada uno desencadena un comportamiento diferente y, sin usar esta forma dinámica de sobrecarga, requeriría cuatro funciones separadas.
Así es como uno puede discernir entre todas estas opciones en inglés y luego las combinaré todas en código:
Si el primer argumento que se pasa a
.data()
es una cadena y el segundo argumento esundefined
, entonces la persona que llama debe utilizar este formulario.Si el segundo argumento no está indefinido, establezca el valor de una clave en particular.
Si no se pasan argumentos, devuelva todas las claves / valores en un objeto devuelto.
Si el tipo del primer argumento es un objeto simple, establezca todas las claves / valores de ese objeto.
Así es como puede combinar todos ellos en un conjunto de lógica de JavaScript:
La clave de esta técnica es asegurarse de que todas las formas de argumentos que desea aceptar sean identificables de forma única y que nunca haya confusión sobre la forma que utiliza la persona que llama. Esto generalmente requiere ordenar los argumentos de manera adecuada y asegurarse de que haya suficiente singularidad en el tipo y la posición de los argumentos para que siempre pueda saber qué forma se está utilizando.
Por ejemplo, si tiene una función que toma tres argumentos de cadena:
Puede hacer que el tercer argumento sea opcional y puede detectar fácilmente esa condición, pero no puede hacer que solo el segundo argumento sea opcional porque no puede decir cuál de estos quiere pasar la persona que llama porque no hay forma de identificar si el segundo El argumento está destinado a ser el segundo argumento o el segundo argumento se omitió, por lo que lo que está en el lugar del segundo argumento es en realidad el tercer argumento:
Dado que los tres argumentos son del mismo tipo, no puede distinguir la diferencia entre los diferentes argumentos, por lo que no sabe lo que pretendía la persona que llama. Con este estilo de llamada, solo el tercer argumento puede ser opcional. Si quisiera omitir el segundo argumento, tendría que pasarlo como
null
(o algún otro valor detectable) en su lugar y su código detectaría eso:Aquí hay un ejemplo de jQuery de argumentos opcionales. Ambos argumentos son opcionales y toman valores predeterminados si no se pasan:
Aquí hay un ejemplo de jQuery en el que puede faltar el argumento o cualquiera de los tres tipos diferentes, lo que le brinda cuatro sobrecargas diferentes:
Argumentos nombrados
Otros lenguajes (como Python) permiten pasar argumentos con nombre como un medio para pasar solo algunos argumentos y hacer que los argumentos sean independientes del orden en que se pasan. Javascript no admite directamente la función de argumentos con nombre. Un patrón de diseño que se usa comúnmente en su lugar es pasar un mapa de propiedades / valores. Esto se puede hacer pasando un objeto con propiedades y valores o en ES6 y superior, podría pasar un objeto Map en sí.
Aquí hay un ejemplo simple de ES5:
jQuery's
$.ajax()
acepta una forma de uso en la que simplemente le pasa un único parámetro que es un objeto Javascript normal con propiedades y valores. Las propiedades que le pase determinan qué argumentos / opciones se pasan a la llamada ajax. Algunos pueden ser necesarios, muchos son opcionales. Dado que son propiedades de un objeto, no existe un orden específico. De hecho, hay más de 30 propiedades diferentes que se pueden pasar a ese objeto, solo se requiere una (la URL).He aquí un ejemplo:
Dentro de la
$.ajax()
implementación, puede simplemente interrogar qué propiedades se pasaron en el objeto entrante y usarlas como argumentos con nombre. Esto se puede hacer confor (prop in obj)
o incorporando todas las propiedades en una matrizObject.keys(obj)
y luego iterando esa matriz.Esta técnica se usa muy comúnmente en Javascript cuando hay una gran cantidad de argumentos y / o muchos argumentos son opcionales. Nota: esto impone la responsabilidad de la función de implementación para asegurarse de que haya un conjunto mínimo de argumentos válidos y para darle a la persona que llama algunos comentarios de depuración sobre lo que falta si se pasan argumentos insuficientes (probablemente lanzando una excepción con un mensaje de error útil) .
En un entorno ES6, es posible utilizar la desestructuración para crear propiedades / valores predeterminados para el objeto pasado anteriormente. Esto se discute con más detalle en este artículo de referencia .
Aquí hay un ejemplo de ese artículo:
Esto crea propiedades y valores predeterminados para las propiedades
start
,end
ystep
en un objeto pasado a laselectEntries()
función.Valores predeterminados para argumentos de función
En ES6, Javascript agrega soporte de lenguaje integrado para valores predeterminados para argumentos.
Por ejemplo:
Descripción adicional de las formas en que esto se puede utilizar aquí en MDN .
fuente
resetProgressBar: function(display_errors, lockout = false)
.La sobrecarga de una función en JavaScript se puede realizar de muchas formas. Todos ellos involucran una única función maestra que realiza todos los procesos o delega en subfunciones / procesos.
Una de las técnicas simples más comunes implica un simple cambio:
Una técnica más elegante sería usar una matriz (u objeto si no está haciendo sobrecargas para cada argumento):
Ese ejemplo anterior no es muy elegante, cualquiera podría modificarlo
fooArr
y fallaría si alguien pasa más de 2 argumentos afoo
, por lo que una mejor forma sería usar un patrón de módulo y algunas verificaciones:Por supuesto, sus sobrecargas pueden querer usar un número dinámico de parámetros, por lo que podría usar un objeto para la
fns
colección.Mi preferencia personal tiende a ser el
switch
, aunque aumenta la función maestra. Un ejemplo común de dónde usaría esta técnica sería un método de acceso / mutador:fuente
No puede realizar una sobrecarga de métodos en sentido estricto. No como la forma en que se admite en
java
oc#
.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 anterior va a mi blog personal que tiene detalles adicionales sobre esto.
fuente
Estoy usando un enfoque de sobrecarga un poco diferente según el número de argumentos. Sin embargo, creo que el enfoque de John Fawcett también es bueno. Aquí el ejemplo, código basado en las explicaciones de John Resig (Autor de jQuery).
usabilidad:
fuente
En javascript, puede implementar la función solo una vez e invocar la función sin los parámetros
myFunc()
. Luego, verifique si las opciones están 'indefinidas'fuente
Intenté desarrollar una solución elegante a este problema que se describe aquí . Y puedes encontrar la demostración aquí . El uso se ve así:
Los métodos utilizados para lograr esto:
fuente
https://github.com/jrf0110/leFunc
fuente
No hay problema con la sobrecarga en JS, el pb ¿cómo mantener un código limpio cuando se sobrecarga la función?
Puede usar un reenvío para tener un código limpio, basado en dos cosas:
Tipo de argumentos (al llamar a la función)
fuente
Mira esto:
http://www.codeproject.com/Articles/688869/Overloading-JavaScript-Functions
Básicamente, en su clase, enumera las funciones que desea que se sobrecarguen y luego, con una llamada de función, agrega la sobrecarga de funciones, rápida y fácilmente.
fuente
Dado que JavaScript no tiene opciones de sobrecarga de funciones , se puede usar el objeto en su lugar. Si hay uno o dos argumentos necesarios, es mejor mantenerlos separados del objeto de opciones. A continuación, se muestra un ejemplo sobre cómo utilizar el objeto de opciones y los valores rellenados 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
Para esto, necesita crear una función que agregue la función a un objeto, luego se ejecutará dependiendo de la cantidad de argumentos que envíe a la función:
fuente
Me gusta agregar subfunciones dentro de una función principal para lograr la capacidad de diferenciar entre grupos de argumentos para la misma funcionalidad.
fuente
Lo que está tratando de lograr se hace mejor utilizando la variable de argumentos locales de la función .
Puede encontrar una mejor explicación de cómo funciona esto aquí .
fuente