style - Verificación nula de JavaScript
title label html (7)
He encontrado el siguiente código:
function (data) {
if (data != null && data !== undefined) {
// some code here
}
}
Soy algo nuevo en JavaScript, pero, por otras preguntas que he estado leyendo aquí, tengo la impresión de que este código no tiene mucho sentido.
Obtendrá un error si accede a una variable indefinida en cualquier contexto que no seatypeof
.
Actualización: la respuesta (de la cita de) anterior puede ser engañosa. Debería decir «una variable no declarada» , en lugar de «una variable indefinida» .
Como descubrí, en las respuestas de Ryan ♦ , maerics y nwellnhof , incluso cuando no se proporcionan argumentos a una función, sus variables para los argumentos siempre se declaran. Este hecho también prueba que es incorrecto el primer elemento en la lista a continuación.
Desde mi entendimiento, los siguientes escenarios pueden ser experimentados:
La función se invocó sin argumentos, convirtiendo losdata
una variable indefinida y provocando un error en losdata != null
.La función se llamó específicamente con
null
(oundefined
), como su argumento, en cuyo casodata != null
ya protege el código interno, lo que hace que&& data !== undefined
useless.La función fue llamada con un argumento no nulo, en cuyo caso pasará trivialmente ambos
data != null
ydata !== undefined
.
P: ¿Es correcto mi entendimiento?
He intentado lo siguiente, en la consola de Firefox:
--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true
No puedo encontrar un caso en el que los data !== undefined
después de los data != null
puedan ser de alguna utilidad.
Creo que probar variables para valores que no esperas no es una buena idea en general. Debido a que la prueba puede considerar como escribir una lista negra de valores prohibidos. Pero, ¿y si te olvidas de enumerar todos los valores prohibidos? Alguien, incluso usted, puede descifrar su código pasando un valor inesperado. Por lo tanto, un enfoque más apropiado es algo así como incluir en la lista blanca: probar variables solo para los valores esperados, no inesperados. Por ejemplo, si espera que el valor de los datos sea una cadena, en lugar de esto:
function (data) {
if (data != null && data !== undefined) {
// some code here
// but what if data === false?
// or data === '''' - empty string?
}
}
haz algo como esto:
function (data) {
if (typeof data === ''string'' && data.length) {
// consume string here, it is here for sure
// cleaner, it is obvious what type you expect
// safer, less error prone due to implicit coercion
}
}
En JavaScript, null
es un objeto singleton especial que es útil para señalar "sin valor". Puede probarlo en comparación y, como es habitual en JavaScript, es una buena práctica usar el operador ===
para evitar confusiones de tipo de coerción:
var a = null;
alert(a === null); // true
Como @rynah menciona, "indefinido" es un poco confuso en JavaScript. Sin embargo, siempre es seguro probar si el tipo de typeof(x)
es la cadena "indefinida", incluso si "x" no es una variable declarada:
alert(typeof(x) === ''undefined''); // true
Además, las variables pueden tener el "valor indefinido" si no se inicializan:
var y;
alert(typeof(y) === ''undefined''); // true
Poniendo todo junto, su cheque debería verse así:
if ((typeof(data) !== ''undefined'') && (data !== null)) {
// ...
Sin embargo, dado que la variable "datos" siempre se define porque es un parámetro de función formal, no es necesario utilizar el operador "typeof" y puede comparar de forma segura directamente con el "valor indefinido".
function(data) {
if ((data !== undefined) && (data !== null)) {
// ...
Este fragmento equivale a decir "si se llamó a la función con un argumento que está definido y no es nulo ..."
La forma más simple de hacer tu prueba es:
function (data) {
if (data) { // check if null, undefined, empty ...
// some code here
}
}
Una "variable indefinida" es diferente del valor undefined
.
Una variable indefinida:
var a;
alert(b); // ReferenceError: b is not defined
Una variable con el valor undefined
:
var a;
alert(a); // Alerts “undefined”
Cuando una función toma un argumento, ese argumento siempre se declara incluso si su valor undefined
está undefined
, por lo que no habrá ningún error. Sin embargo, tienes razón sobre != null
seguido de !== undefined
siendo inútil.
typeof foo === "undefined"
es diferente de foo === undefined
, nunca confundirlos. typeof foo === "undefined"
es lo que realmente necesitas. Además, use !==
en lugar de !=
Entonces la declaración se puede escribir como
function (data) {
if (typeof data !== "undefined" && data !== null) {
// some code here
}
}
Editar:
No puede usar foo === undefined
para variables no declaradas.
var t1;
if(typeof t1 === "undefined")
{
alert("cp1");
}
if(t1 === undefined)
{
alert("cp2");
}
if(typeof t2 === "undefined")
{
alert("cp3");
}
if(t2 === undefined) // fails as t2 is never declared
{
alert("cp4");
}
P: La función se invocó sin argumentos, lo que convierte los datos en una variable indefinida y genera un error en los datos! = Null.
A: Sí, los data
se definirán como indefinidos. Consulte la sección 10.5 Creación de declaraciones de unión de la especificación. Pero acceder a un valor indefinido no genera un error. Probablemente estés confundiendo esto con acceder a una variable no declarada en modo estricto, lo que genera un error.
P: La función se llamó específicamente con nulo (o indefinido), como su argumento, en cuyo caso data! = Null ya protege el código interno, lo que hace que && data! == undefined useless.
P: La función se invocó con un argumento no nulo, en cuyo caso pasará trivialmente ambos datos! = Null y data! == undefined.
A: Correcto. Tenga en cuenta que las siguientes pruebas son equivalentes:
data != null
data != undefined
data !== null && data !== undefined
Consulte la sección 11.9.3 El algoritmo de comparación de igualdad abstracta y la sección 11.9.6 El algoritmo de comparación de igualdad estricta de la especificación.
var a;
alert(a); //Value is undefined
var b = "Volvo";
alert(b); //Value is Volvo
var c = null;
alert(c); //Value is null