Ahora he visto 2 métodos para determinar si se ha pasado un argumento a una función de JavaScript. Me pregunto si un método es mejor que el otro o si uno es malo de usar.
function Test(argument1, argument2) {
if (Test.arguments.length == 1) argument2 = 'blah';
alert(argument2);
}
Test('test');
O
function Test(argument1, argument2) {
argument2 = argument2 || 'blah';
alert(argument2);
}
Test('test');
Por lo que puedo decir, ambos resultan en lo mismo, pero solo he usado el primero antes en producción.
Otra opción mencionada por Tom :
function Test(argument1, argument2) {
if(argument2 === null) {
argument2 = 'blah';
}
alert(argument2);
}
Según el comentario de Juan, sería mejor cambiar la sugerencia de Tom para:
function Test(argument1, argument2) {
if(argument2 === undefined) {
argument2 = 'blah';
}
alert(argument2);
}
javascript
arguments
Darryl Hein
fuente
fuente
argument2 || 'blah';
dará como resultado 'blah' siargument2
esfalse
(!), No simplemente si no está definido. Siargument2
es un booleano y se le pasa la funciónfalse
, esa línea devolverá 'blah' a pesar deargument2
estar definida correctamente .argument2
es0
,''
onull
.Respuestas:
Hay varias formas diferentes de verificar si se pasó un argumento a una función. Además de los dos que mencionó en su pregunta (original), verificando
arguments.length
o usando el||
operador para proporcionar valores predeterminados, uno también puede verificar explícitamente los argumentos paraundefined
víaargument2 === undefined
otypeof argument2 === 'undefined'
si uno es paranoico (ver comentarios).Usando el
||
operador ha convertido en una práctica estándar - todos los niños frescos lo hacen - pero tenga cuidado: El valor por defecto se activa si los argumentos evalúa afalse
, lo que significa que en realidad podría serundefined
,null
,false
,0
,''
(o cualquier otra cosa para la queBoolean(...)
vuelvefalse
).Entonces, la pregunta es cuándo usar qué verificación, ya que todas producen resultados ligeramente diferentes.
Comprobación
arguments.length
exhibe el comportamiento 'más correcto', pero podría no ser factible si hay más de un argumento opcional.La prueba para
undefined
es el próximo 'mejor': solo 'falla' si la función se llama explícitamente con unundefined
valor, que probablemente debería tratarse de la misma manera que omitiendo el argumento.El uso de la
||
operador puede desencadenar el uso del valor predeterminado incluso si se proporciona un argumento válido. Por otro lado, su comportamiento podría ser realmente deseado.Para resumir: ¡Úselo solo si sabe lo que está haciendo!
En mi opinión, el uso
||
también es el camino a seguir si hay más de un argumento opcional y uno no quiere pasar un objeto literal como solución para los parámetros con nombre.Otra buena manera de proporcionar valores predeterminados usando
arguments.length
es posible cayendo a través de las etiquetas de una declaración de cambio:Esto tiene el inconveniente de que la intención del programador no es (visualmente) obvia y utiliza 'números mágicos'; Por lo tanto, es posible que sea propenso a errores.
fuente
Si está usando jQuery, una opción que es buena (especialmente para situaciones complicadas) es usar el método extendido de jQuery .
Si llama a la función, entonces así:
La variable de opciones sería entonces:
fuente
Este es uno de los pocos casos en los que encuentro la prueba:
funciona bastante bien y conlleva la implicación correcta sintácticamente.
(Con la restricción simultánea de que no permitiría un valor nulo legítimo para el
argument2
que tiene algún otro significado; pero eso sería realmente confuso).EDITAR:
Este es un muy buen ejemplo de una diferencia estilística entre lenguajes poco tipados y fuertemente tipados; y una opción estilística que JavaScript ofrece en espadas.
Mi preferencia personal (sin críticas para otras preferencias) es el minimalismo. Cuanto menos tenga que decir el código, mientras sea coherente y conciso, menos tendrá que comprender alguien más para inferir correctamente mi significado.
Una implicación de esa preferencia es que no quiero, no me parece útil, acumular un montón de pruebas de dependencia de tipo. En cambio, trato de hacer que el código signifique lo que parece; y prueba solo para lo que realmente tendré que probar.
Una de las molestias que encuentro en el código de otras personas es saber si esperan o no, en un contexto más amplio, encontrarse con los casos que están probando. O si están tratando de probar todo lo posible, en la posibilidad de que no anticipen el contexto lo suficiente. Lo que significa que termino necesitando rastrearlos exhaustivamente en ambas direcciones antes de poder refactorizar o modificar cualquier cosa con confianza. Me imagino que hay una buena posibilidad de que hayan implementado esas diversas pruebas porque previeron circunstancias en las que serían necesarias (y que generalmente no son aparentes para mí).
(Considero que es una desventaja grave en la forma en que estas personas usan lenguajes dinámicos. Con demasiada frecuencia, las personas no quieren renunciar a todas las pruebas estáticas y terminan fingiendo).
He visto esto de manera más evidente al comparar el código completo de ActionScript 3 con el elegante código de JavaScript. El AS3 puede ser 3 o 4 veces el grueso del js, y la confiabilidad que sospecho no es al menos mejor, solo por la cantidad (3-4X) de decisiones de codificación que se tomaron.
Como dices, Shog9, YMMV. :RE
fuente
Hay diferencias significativas Configuremos algunos casos de prueba:
Con el primer método que describa, solo la segunda prueba usará el valor predeterminado. El segundo método por defecto todos excepto el primero (como JS convertirá
undefined
,null
,0
, y""
en el booleanofalse
. Y si usted fuera a utilizar el método de Tom, sólo la cuarta prueba usará el valor por defecto!El método que elija realmente depende de su comportamiento previsto. Si
undefined
se permiten valores distintos deargument2
, probablemente querrá alguna variación en el primero; si se desea un valor no cero, no nulo, no vacío, entonces el segundo método es ideal; de hecho, a menudo se usa para eliminar rápidamente un rango tan amplio de valores de la consideración.fuente
fuente
En ES6 (ES2015) puede usar parámetros predeterminados
fuente
"default value"
y verificando si el valor es realmente"default value"
.Lo siento, todavía no puedo comentar, así que para responder la respuesta de Tom ... En javascript (undefined! = Null) == false De hecho, esa función no funcionará con "null", debe usar "undefined"
fuente
¿Por qué no usar el
!!
operador? Este operador, colocada antes de la variable, lo convierten a un valor lógico (si he entendido bien), por lo que!!undefined
y!!null
(e incluso!!NaN
, que puede ser muy interesante) devolveráfalse
.Aquí hay un ejemplo:
fuente
Puede ser conveniente abordar la detección de argumentos evocando su función con un Objeto de propiedades opcionales:
fuente
También hay una manera difícil de encontrar, si un parámetro se pasa a una función o no . Echa un vistazo al siguiente ejemplo:
Esto significa que si el valor de
value
no está presente / pasado, configúrelo en 0.Muy bien, ¿eh?
fuente
value
es equivalente afalse
, configúrelo en 0". Esta es una distinción sutil pero muy importante.true
yfalse
son valores válidos, y es posible que desee tener un tercer comportamiento para cuando el parámetro no está aprobado en todos (especialmente si la función tiene más de un parámetro).Algunas veces también es posible que desee verificar el tipo, especialmente si está utilizando la función como getter y setter. El siguiente código es ES6 (no se ejecutará en EcmaScript 5 o anterior):
fuente
Porque las matrices heredan de
Object.prototype
. Considere ⇑ para mejorar el mundo.fuente
fnCalledFunction (Param1, Param2, window.YourOptionalParameter)
Si la función anterior se llama desde muchos lugares y está seguro de que los primeros 2 parámetros se pasan desde todas partes, pero no está seguro sobre el tercer parámetro, puede usar la ventana.
window.param3 se encargará si no está definido desde el método de la persona que llama.
fuente