¿Podría alguien explicarme la diferencia entre if(obj.x == undefined) y if(typeof obj.x == 'undefined')

En algún contexto, el primero funciona bien, pero en otro, necesito usar el segundo.

Preguntas

1 - ¿Cuál es la diferencia entre las dos condiciones?

2 - ¿Hay una mejor práctica?

6
David Laberge 29 ago. 2011 a las 18:58

5 respuestas

La mejor respuesta

La mejor práctica es no solo verificar la veracidad sino la igualdad estricta

Ejemplo

if (obj.x === undefined) {}

Esto solía ser un problema porque undefined (una propiedad global) solía ser grabable, ya que desde 1.8.5 no se puede escribir, lo que le proporciona una comparación segura en entornos de especificaciones ES5.

Por MDN

7
jondavidjohn 29 ago. 2011 a las 16:01

Las dos no son pruebas equivalentes debido al manejo bastante complicado de los valores especiales por javascript. En el específico

undefined == null

Es cierto, pero typeof undefined es "undefined" mientras que typeof null es "object".

Las reglas para esos valores especiales son bastante complejas e IMO ilógicas, por lo que creo que no hay una "regla general". Lo que puede encontrar son formas comunes, por ejemplo

var value = obj.x || default_value;

Eso se puede usar si está seguro de que obj nunca será undefined o null (porque en ese caso se lanzaría una excepción) y suponiendo que 0, NaN o una cadena vacía debe considerarse como si no se proporcionara ningún valor (porque todos son valores "lógicamente falsos"). En cambio, una matriz vacía o un objeto javascript vacío se consideran "lógicamente verdaderos".

¿Por qué es así? ¿Por qué (null).x arroja una excepción cuando null según typeof es aparentemente un objeto y la búsqueda de un campo inexistente en un objeto normalmente devuelve undefined?

No tengo idea.

Nunca intenté encontrar una lógica en todas esas extrañas reglas. En realidad, ni siquiera estoy 100% seguro de que haya uno.

Mi sugerencia es solo estudiar y experimentar con ellos.

1
6502 29 ago. 2011 a las 17:39

La mejor manera de probar la condicionalidad es utilizando obj.x, esto verifica tanto la capacidad nula como la indefinida.

Así

if(!obj.x) 
{
  alert(obj.x);
}
else   
{
  alert("obj.x is null or undefined");  //obj.x is null or undefined or any false value which is what you want. like obj.x is false or 0
}
0
Baz1nga 29 ago. 2011 a las 15:19

El segundo es más fácil y rápido que el primero. Primero requiere configuración adicional, definición de indefinido y verificar si obj contiene x como una propiedad o método. segundo hace la comprobación de si obj.x ha sido siempre definido y asignado

PS .: undefined se evaluará como nulo, por lo que obj.x == undefined es equivalente a obj.x == null

0
i100 29 ago. 2011 a las 15:08

Los dos generalmente serían equivalentes si reemplazara el operador de igualdad == con el operador de igualdad estricta ===. Entonces obj.x === undefined y typeof obj.x == "undefined" son generalmente equivalentes.

Sin embargo, en entornos anteriores a ECMAScript 5 (que todavía cuentan para la mayoría de las solicitudes web, en general), undefined es una propiedad grabable del objeto global, lo que significa que undefined puede usarse como nombre de variable o la propiedad global puede tener asignado un valor diferente. ECMAScript 5 hace que la propiedad global sea de solo lectura, pero aun así, undefined aún puede usarse como nombre de variable dentro de una función, lo que significa que la verificación typeof siempre es más segura.

Otro punto a favor de typeof es que se puede usar para verificar una variable que no se haya declarado, mientras que una comparación directa arrojará un ReferenceError si la variable no se ha declarado. Por ejemplo:

typeof foo == "undefined" // true
foo === undefined // ReferenceError

Sin embargo, esto es algo inusual y no generalmente útil de hacer.

1
Tim Down 29 ago. 2011 a las 15:33