Pregunta Detectar una propiedad de objeto indefinida


¿Cuál es la mejor manera de verificar si una propiedad de objeto en JavaScript no está definida?


2430
2017-08-26 07:25


origen


Respuestas:


Utilizar:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Si es una variable de objeto que tiene algunas propiedades, puede usar la misma cosa así:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

Desde ECMAScript 5, undefined no se puede sobrescribir, por lo my_obj === undefined funcionaría también, pero solo si my_obj existe Esto puede o no ser deseado porque también puedes usar null si necesitas esta semántica (ver ¿Cuál es la diferencia entre nulo e indefinido en JavaScript?) Sin embargo, para las propiedades del objeto, funciona independientemente de si la propiedad existe.


2316
2018-01-06 12:27



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 robusta de realizar esta prueba es:

if (typeof myVar === "undefined")

Esto siempre devolverá el resultado correcto e incluso maneja la situación donde myVar no está declarado.

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 que myVar no se declara.


803
2017-08-23 18:03



En JavaScript hay nulo y ahí está indefinido. Ellos tienen diferentes significados.

  • indefinido significa que el valor de la variable no ha sido definido; no se sabe cuál es el valor.
  • nulo significa que el valor de la variable está definido y establecido en nulo (no tiene valor).

Marijn Haverbeke afirma, en su libro gratuito en línea "JavaScript elocuente"(el énfasis es mío):

También hay un valor similar, nulo, cuyo significado es 'este valor está definido, pero no tiene un valor'. La diferencia de significado entre indefinido y nulo es principalmente académica, y por lo general no muy interesante. En los programas prácticos, a menudo es necesario verificar si algo 'tiene un valor'. En estos casos, se puede usar la expresión algo == undefined, porque, aunque no tengan exactamente el mismo valor, null == undefined producirá verdadero.

Entonces, supongo que la mejor manera de verificar si algo no está definido sería:

if (something == undefined)

¡Espero que esto ayude!

Editar: En respuesta a su edición, las propiedades del objeto deberían funcionar de la misma manera.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

133
2017-08-26 07:36



A pesar de ser recomendado con vehemencia por muchas otras respuestas aquí, typeof  es una mala elección. Nunca debe usarse para verificar si las variables tienen el valor undefined, porque actúa como un control combinado para el valor undefined y por si existe una variable. En la gran mayoría de los casos, usted sabe cuándo existe una variable, y typeof solo introducirá el potencial de una falla silenciosa si crea un error tipográfico en el nombre de la variable o en el literal de la 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é haciendo detección de características², donde hay incertidumbre sobre si un nombre dado estará dentro del alcance (como verificar typeof module !== 'undefined' como un paso en el código específico de un entorno CommonJS), typeof es una opció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 leyendo 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 puede ser sobrescrito Hay mucho más para esto. undefined no es una palabra clave en JavaScript. En cambio, es una propiedad en el objeto global con el valor indefinido. Sin embargo, desde ES5, esta propiedad ha sido solo lectura y no configurable. Ningún navegador moderno permitirá el undefined propiedad a ser cambiada, y a partir de 2017 este ha sido el caso durante mucho tiempo. La falta de modo estricto no afecta undefinedTampoco, simplemente hace declaraciones como undefined = 5 no hacer nada en lugar de tirar. Sin embargo, dado que no es una palabra clave, puedes declarar variables con el nombre undefined, y esas variables podrían cambiarse, haciendo este patrón una vez común:

    (function (undefined) {
        // …
    })()
    

    Más peligroso que usar el global undefined. Si tiene que ser compatible con ES3, reemplace undefined con void 0 - no recurrir a typeof. (void siempre ha sido un operador unario que evalúa el valor indefinido para cualquier operando).

Con la forma en que las variables funcionan fuera del camino, es hora de abordar la pregunta real: 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ás usando typeof, porque tiene más sentido usar === para verificar la igualdad, porque podría refactorizarse para verificar el valor de una variable más adelante, y porque simplemente se ve mejor, siempre debes usar === undefined³ aquí también.

Otra cosa a considerar cuando se trata de propiedades de objetos 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 cualquier parte de la cadena de prototipos de un objeto, y Object.prototype.hasOwnProperty.call(obj, 'key') le dirá si está directamente en el objeto. Sin embargo, no voy a entrar en detalles en esta respuesta sobre prototipos y el uso de objetos como mapas de clave de cuerda, porque en su mayoría está destinada a contrarrestar todos los malos consejos en otras respuestas, independientemente de las posibles interpretaciones de la pregunta original. Leer sobre prototipos de objetos en MDN ¡para más!

¹ elección inusual del nombre de variable de ejemplo? este es un código muerto real de la extensión NoScript para Firefox.
² no asumo que no saber lo que está en el alcance está bien en general, sin embargo. vulnerabilidad de bonificación causada por el abuso del alcance dinámico: Proyecto Zero 1225
³ una vez más asumiendo un ambiente ES5 + y eso undefined se refiere a undefined propiedad del objeto global. sustituir void 0 de otra manera.


130
2018-02-26 21:17



Qué significa esto: "propiedad de objetos indefinidos"?

¡De hecho, puede significar dos cosas completamente diferentes! Primero, puede significar la propiedad que nunca ha sido definida en el objeto y, en segundo lugar, puede significar el propiedad que tiene un valor indefinido. Veamos este código:

var o = { a: undefined }

Es o.a indefinido? ¡Sí! Su valor no está definido. Es o.b indefinido? ¡Por supuesto! ¡No existe la propiedad 'b' en absoluto! OK, mira ahora cómo se comportan los diferentes enfoques en ambas situaciones:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Podemos ver claramente eso typeof obj.prop == 'undefined' y obj.prop === undefined son equivalentes, y no distinguen esas situaciones diferentes. Y 'prop' in obj puede detectar la situación cuando una propiedad no se ha definido en absoluto y no presta atención al valor de la propiedad que puede estar indefinido.

¿Entonces lo que hay que hacer?

1) Desea saber si una propiedad no está definida por el primer o segundo significado (la situación más típica).

obj.prop === undefined // IMHO, see "final fight" below

2) Quiere saber si el objeto tiene alguna propiedad y no le importa su valor.

'prop' in obj

Notas:

  • No puede verificar un objeto y su propiedad al mismo tiempo. Por ejemplo, esto x.a === undefined o esto typeof x.a == 'undefined' plantea ReferenceError: x is not defined si x no está definido.
  • Variable undefined es una variable global (por lo que en realidad es window.undefined en navegadores). Ha sido compatible desde ECMAScript 1st Edition y desde ECMAScript 5 es solo lectura. Entonces en los navegadores modernos no puede ser redefinido a verdadero como muchos autores nos quieren asustar, pero esto sigue siendo cierto para los navegadores más antiguos.

Lucha final: obj.prop === undefined vs typeof obj.prop == 'undefined'

Ventajas de obj.prop === undefined:

  • Es un poco más corto y se ve un poco más bonito
  • El motor de JavaScript le dará un error si ha escrito mal undefined

Desventajas de obj.prop === undefined:

  • undefined puede anularse en navegadores antiguos

Ventajas de typeof obj.prop == 'undefined':

  • ¡Es realmente universal! Funciona en navegadores nuevos y antiguos.

Desventajas de typeof obj.prop == 'undefined':

  • 'undefned' (mal escrito) aquí solo hay una constante de cadena, por lo que el motor de JavaScript no puede ayudarlo si lo ha escrito mal como lo acabo de hacer.

Actualización (para el lado del servidor de JavaScript):

Node.js admite la variable global undefined como global.undefined (también se puede usar sin el prefijo 'global'). No sé sobre otras implementaciones de JavaScript del lado del servidor.


100
2017-08-08 20:28



El problema se reduce a tres casos:

  1. El objeto tiene la propiedad y su valor no es undefined.
  2. El objeto tiene la propiedad y su valor es undefined.
  3. El objeto no tiene la propiedad.

Esto nos dice algo que considero importante:

Existe una diferencia entre un miembro indefinido y un miembro definido con un valor indefinido.

Pero infelizmente typeof obj.foo no nos dice cuál de los tres casos tenemos. Sin embargo, podemos combinar esto con "foo" in objpara distinguir los casos.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Vale la pena señalar que estas pruebas son las mismas para null entradas también

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Yo argumentaría que en algunos casos tiene más sentido (y es más claro) verificar si la propiedad está allí, que verificar si está indefinida, y el único caso en el que esta verificación será diferente es el caso 2, el raro caso de una entrada real en el objeto con un valor indefinido.

Por ejemplo: acabo de refactorizar un montón de código que tenía un montón de comprobaciones de si un objeto tenía una propiedad determinada.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Lo cual fue más claro cuando se escribió sin un cheque para indefinido.

if( "x" in blob ) { fn(blob.x); }

Pero como se ha mencionado, estos no son exactamente iguales (pero son más que suficientes para mis necesidades).


59
2018-06-08 04:04



if ( typeof( something ) == "undefined") 

Esto funcionó para mí mientras que los otros no.


38
2017-07-27 16:03



No estoy seguro de dónde está el origen del uso === con typeof vinieron de, y como una convención, lo veo utilizado en muchas bibliotecas, pero el operador typeof devuelve una cadena literal, y lo sabemos desde el principio, entonces ¿por qué también querrías tipearlo también?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

33
2017-09-22 14:20