Saltar al contenido

Detectar una propiedad de objeto indefinida

Solución:

La forma habitual de comprobar si el valor de una propiedad es el valor especial undefined, es:

if(o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

Para comprobar si un objeto no tiene realmente dicha propiedad y, por lo tanto, devolverá undefined de forma predeterminada cuando intentas acceder a él:

if(!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

Para comprobar si el valor asociado con un identificador es el valor especial undefined, o si ese identificador no ha sido declarado. Nota: este método es la única forma de referirse a un no declarado (nota: diferente de tener un valor de undefined) identificador sin un error temprano:

if(typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

En versiones de JavaScript anteriores a ECMAScript 5, la propiedad denominada “undefined” en el objeto global se podía escribir y, por lo tanto, una simple verificación foo === undefined podría comportarse inesperadamente si se hubiera redefinido accidentalmente. En JavaScript moderno, la propiedad es de solo lectura.

Sin embargo, en JavaScript moderno, “indefinido” no es una palabra clave, por lo que las variables dentro de las funciones pueden denominarse “indefinido” y sombrear la propiedad global.

Si está preocupado por este caso de borde (poco probable), puede utilizar el operador de vacío para obtener el especial undefined valor en sí mismo:

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}

Creo que hay varias respuestas incorrectas a este tema. Contrariamente a la creencia común, “indefinido” es no una palabra clave en JavaScript y, de hecho, puede tener un valor asignado.

Código correcto

La forma más sólida de realizar esta prueba es:

if (typeof myVar === "undefined")

Esto siempre devolverá el resultado correcto e incluso maneja la situación en la que myVar no se declara.

Código degenerado. NO UTILICE.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Adicionalmente, myVar === undefined generará un error en la situación en la que myVar no se declara.

A pesar de ser recomendado con vehemencia por muchas otras respuestas aquí, typeof es una mala eleccion. Nunca debe usarse para verificar si las variables tienen el valor undefined, porque actúa como una verificación combinada del valor undefined y si existe una variable. En la gran mayoría de los casos, sabe cuándo existe una variable y typeof simplemente introducirá la posibilidad de una falla silenciosa si comete un error tipográfico en el nombre de la variable o en el literal de cadena 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Entonces, a menos que esté realizando una detección de características², donde no hay certeza de si un nombre de pila estará dentro del alcance (como verificar typeof module !== 'undefined' como un paso en el código específico para un entorno CommonJS), typeof es una elección dañina cuando se usa en una variable, y la opción correcta es comparar el valor directamente:

var foo = …;

if (foo === undefined) {
    ⋮
}

Algunos conceptos erróneos comunes sobre esto incluyen:

  • que leer una variable “no inicializada” (var foo) o parámetro (function bar(foo) { … }, llamado bar()) fallará. Esto simplemente no es cierto: las variables sin inicialización explícita y los parámetros a los que no se les dieron valores siempre se vuelven undefinedy siempre están dentro del alcance.

  • ese undefined se puede sobrescribir. Eso es verdad undefined no es una palabra clave, pero es de solo lectura y no configurable. Hay otras funciones integradas que probablemente no evite a pesar de su estado sin palabras clave (Object, Math, NaN…) y el código práctico no suele estar escrito en un entorno activamente malicioso, por lo que esta no es una buena razón para preocuparse. undefined. (Pero si está escribiendo un generador de código, no dude en usar void 0.)

Con cómo funcionan las variables, es hora de abordar la pregunta real: las propiedades del objeto. No hay razón para usar typeof para las propiedades del objeto. La excepción anterior con respecto a la detección de características no se aplica aquí: typeof solo tiene un comportamiento especial en las variables, y las expresiones que hacen referencia a las propiedades del objeto no son variables.

Esta:

if (typeof foo.bar === 'undefined') {
    ⋮
}

es siempre exactamente equivalente a esto³:

if (foo.bar === undefined) {
    ⋮
}

y teniendo en cuenta los consejos anteriores, para evitar confundir a los lectores sobre por qué está utilizando typeof, porque tiene más sentido usar === para verificar la igualdad, porque podría refactorizarse para verificar el valor de una variable más tarde, y porque simplemente se ve mejor, siempre deberías usar === undefined³ aquí también.

Otra cosa a considerar cuando se trata de propiedades de objeto es si realmente desea verificar undefined en absoluto. Un nombre de propiedad dado puede estar ausente en un objeto (produciendo el valor undefined cuando se lee), presente en el objeto mismo con el valor undefined, presente en el prototipo del objeto con el valor undefined, o presente en cualquiera de los que no tienenundefined valor. 'key' in obj le dirá si una clave está en algún lugar de la cadena de prototipo de un objeto, y Object.prototype.hasOwnProperty.call(obj, 'key') le dirá si está directamente sobre el objeto. Sin embargo, no entraré en detalles en esta respuesta sobre los prototipos y el uso de objetos como mapas con claves de cadena, porque su objetivo principal es contrarrestar todos los malos consejos en otras respuestas, independientemente de las posibles interpretaciones de la pregunta original. ¡Lea sobre prototipos de objetos en MDN para obtener más información!

¹ elección inusual de nombre de variable de ejemplo? este es un código muerto real de la extensión NoScript para Firefox.
² Sin embargo, no asuma que no saber cuál es el alcance está bien en general. vulnerabilidad adicional causada por abuso de alcance dinámico: Proyecto Zero 1225
³ una vez más asumiendo un entorno ES5 + y que undefined se refiere a undefined propiedad del objeto global.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *