¿Comprobando si existe una clave en un objeto JavaScript?

2973

¿Cómo verifico si existe una clave particular en un objeto o matriz de JavaScript?

Si no existe una clave e intento acceder a ella, ¿devolverá false? O arrojar un error?

Adam Ernst
fuente
2
Todo (casi todo) en JavaScript es un Objeto o puede ser lanzado como uno. Aquí es donde nacen las matrices pseudo asociativas, como señaló @PatrickM.
Andrew Larsson
Este punto de referencia jsben.ch/#/WqlIl le ofrece una visión general sobre las formas más comunes de cómo lograr esta verificación.
EscapeNetscape
una solución rápida, generalmente busco property.key = property.key || 'some default value', en caso de que quiera que esa clave exista con algún valor
RGLSV

Respuestas:

4121

Comprobar la indefinición no es una forma precisa de comprobar si existe una clave. ¿Qué pasa si la clave existe pero el valor es realmente undefined?

var obj = { key: undefined };
obj["key"] !== undefined // false, but the key exists!

En su lugar, debe usar el inoperador:

"key" in obj // true, regardless of the actual value

Si desea verificar si una clave no existe, recuerde usar paréntesis:

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"

O, si desea probar particularmente las propiedades de la instancia del objeto (y no las propiedades heredadas), use hasOwnProperty:

obj.hasOwnProperty("key") // true

Para la comparación del rendimiento entre los métodos que son in, hasOwnPropertyy la clave es undefined, vea este punto de referencia

Ates Goral
fuente
83
Tener una propiedad con un valor de indefinido definido manualmente no tiene ningún sentido. Sería realmente un oxímoron.
joebert
259
Estoy convencido de que hay casos de uso para tener propiedades configuradas intencionalmente como indefinidas.
Ates Goral
168
Caso de uso válido: Gecko 1.9.1 [Firefox 3.5] no tiene la propiedad window.onhashchange. Gecko 1.9.2 [Firefox 3.6] tiene esta propiedad establecida como indefinida (hasta que cambie el hash). Para detectar el historial de hash o la versión del navegador, se debe usar window.hasOwnProperty ("onhashchange");
SamGoody
77
Existe un problema similar en PHP donde null == inexistente: stackoverflow.com/q/418066/372654 y desafortunadamente, null también tiene un uso allí.
Halil Özgür
80
@joebert El hecho de que algo no tenga sentido no significa que no lo encontrarás en el código de producción. Hay muchas bibliotecas que hacen cosas sin sentido.
Crashworks
298

respuesta rápida

¿Cómo verifico si existe una clave particular en un objeto o matriz de JavaScript? Si no existe una clave e intento acceder a ella, ¿devolverá false? O arrojar un error?

Acceder directamente a una propiedad que falta utilizando el estilo de matriz (asociativo) o el estilo de objeto devolverá una constante indefinida .

El operador lento y confiable en el método hasOwnProperty

Como la gente ya ha mencionado aquí, podría tener un objeto con una propiedad asociada con una constante "indefinida".

 var bizzareObj = {valid_key:  undefined};

En ese caso, tendrá que usar hasOwnProperty o en operator para saber si la clave está realmente allí. Pero, pero a qué precio?

así que te digo ...

en operator y hasOwnProperty son "métodos" que utilizan el mecanismo Descriptor de propiedades en Javascript (similar a la reflexión de Java en el lenguaje Java).

http://www.ecma-international.org/ecma-262/5.1/#sec-8.10

El tipo de descriptor de propiedad se utiliza para explicar la manipulación y la reificación de los atributos de propiedad con nombre. Los valores del tipo Descriptor de propiedad son registros compuestos de campos con nombre donde el nombre de cada campo es un nombre de atributo y su valor es un valor de atributo correspondiente como se especifica en 8.6.1. Además, cualquier campo puede estar presente o ausente.

Por otro lado, llamar a un método o clave de objeto utilizará el mecanismo Javascript [[Get]]. ¡Eso es mucho más rápido!

punto de referencia

http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array

Comparación de acceso clave en JS.

Utilizando en operador
var result = "Impression" in array;

El resultado fue

12,931,832 ±0.21% ops/sec      92% slower 
Usando hasOwnProperty
var result = array.hasOwnProperty("Impression")

El resultado fue

16,021,758 ±0.45% ops/sec     91% slower
Acceso a elementos directamente (estilo de paréntesis)
var result = array["Impression"] === undefined

El resultado fue

168,270,439 ±0.13 ops/sec     0.02% slower 
Acceso a elementos directamente (estilo de objeto)
var result = array.Impression  === undefined;

El resultado fue

168,303,172 ±0.20%     fastest

EDITAR: ¿Cuál es la razón para asignar a una propiedad el undefinedvalor?

Esa pregunta me desconcierta. En Javascript, hay al menos dos referencias de objetos ausentes para evitar problemas como este: nully undefined.

nulles el valor primitivo que representa la ausencia intencional de cualquier valor de objeto, o en términos cortos, la falta de valor confirmada . Por otro lado, undefinedes un valor desconocido (no definido). Si hay una propiedad que se usará más tarde con un valor apropiado , considere usar la nullreferencia de uso en lugar de undefinedporque en el momento inicial se confirma que la propiedad carece de valor.

Comparar:

var a = {1: null}; 
console.log(a[1] === undefined); // output: false. I know the value at position 1 of a[] is absent and this was by design, i.e.:  the value is defined. 
console.log(a[0] === undefined); // output: true. I cannot say anything about a[0] value. In this case, the key 0 was not in a[].

Asesorar

Evitar objetos con undefinedvalores. Marque directamente siempre que sea posible y úselo nullpara inicializar valores de propiedad. De lo contrario, utilice el inoperador o hasOwnProperty()método lento .

EDITAR: 04/12/2018 - NO PERTINENTE MÁS

Como la gente ha comentado, las versiones modernas de los motores Javascript (con la excepción de Firefox) han cambiado el enfoque de las propiedades de acceso. La implementación actual es más lenta que la anterior para este caso particular, pero la diferencia entre la clave de acceso y el objeto es despreciable.

rdllopes
fuente
1
¿Todos estos métodos son aceptables en todos los navegadores de uso común, por ejemplo, IE8 +?
Justin
11
+1 para benchmarking. Gracias, esta es exactamente la información que esperaba encontrar. Definitivamente un argumento fuerte para escribir código que nunca asigna o espera que una clave contenga el valor indefinido .
TJ Compton
Tenía curiosidad de cómo se compara Underscore.js's (), así que lo agregué a jsperf ( versión 11 ). Resulta que está en el grupo lento junto con in y hasOwnProperty ().
mpoisot
3
Una razón por la que establecería indefinido en un valor hash es que realmente quería eliminar esa clave de propiedad del hash, pero delete hash[key]es mucho más lenta que hash[key] = undefined . Por supuesto, en este caso no tiene sentido que necesite el inoperador, pero actúa como un contraejemplo de "siempre debemos evitar establecer el valor en indefinido".
Alan Tam
1
Como mencionó @ HüseyinYağlı, si marca el enlace jsperf , el rendimiento ha cambiado significativamente entre los diferentes métodos para la mayoría de los navegadores desde que esta respuesta se escribió originalmente. Firefox es uno de los pocos que aún tiene una ventaja significativa al usar la matriz o los métodos de objeto, pero para muchos otros navegadores las diferencias son insignificantes.
kevinmicke
144

Se volverá undefined.

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"

undefinedEs un valor constante especial. Entonces puedes decir, por ejemplo

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}

Esta es probablemente la mejor manera de verificar si faltan claves. Sin embargo, como se señala en un comentario a continuación, es teóricamente posible que desee tener el valor real undefined. Nunca he necesitado hacer esto y no puedo pensar en una razón por la cual quisiera hacerlo, pero solo para completar, puede usar el inoperador

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}
Eli Courtwright
fuente
8
¿Qué sucede si la clave existe pero el valor en realidad no está definido?
Ates Goral
13
Debe usar === en lugar de == al comparar con indefinido, de lo contrario, nulo se comparará igual a indefinido.
Matthew Crumley
10
Eli tu respuesta no es completamente precisa. Porque de todos modos (y, por supuesto, esto no debería hacerse nunca) indefinido no es un valor constante especial. De hecho, no es una palabra clave reservada y puede sobrescribirla, digamos, por ejemplo, eso var undefined = 42;. Al probar accesorios indefinidos, siempre debes usarlos ((typeof variable) === "undefined").
ssice
1
@ssice undefinedno es una propiedad de escritura según la especificación ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser
1
En versiones anteriores de JavaScript, 'undefined' y 'NaN' eran variables mutables que se podían redefinir o asignar otros valores . Esto fue algo malo. Fue corregido en ECMAScript 5.
jkdev
29
"key" in obj

Es probable que solo pruebe valores de atributos de objeto que sean muy diferentes de las claves de matriz

usuario2320522
fuente
Este código dará verdadero también para una clave que se define en el prototipo de la Clase: función A () {}; A.prototype.b = 2; var a = new A (); Entonces 'b' en a es cierto. Mientras que a.hasOwnProperty ('b') es, por supuesto, falso.
Alexander
24

Tres formas de verificar si una propiedad está presente en un objeto javascript:

  1. !!obj.theProperty
    Convertirá valor a bool. devuelve truepara todos menos el falsevalor
  2. ' theProperty' en obj Devuelve
    verdadero si la propiedad existe, sin importar su valor (incluso vacío)
  3. obj.hasOwnProperty('theProperty')
    No comprueba la cadena del prototipo. (dado que todos los objetos tienen el toStringmétodo, 1 y 2 devolverán verdadero en él, mientras que 3 puede devolver falso en él).

Referencia:

http://book.mixu.net/node/ch5.html

Lavi Avigdor
fuente
!! obj.theProperty falla cuando el valor no está definido. Ej:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN
de revisión: !!obj.thePropertyno es una solución para verificar si un objeto tiene una propiedad llamada theProperty. Falla para cualquier valor de propiedad falsey,, undefinednulo, numérico 0o NaN, y la cadena vacía""
traktor53
15

Si está utilizando la biblioteca underscore.js, las operaciones de objeto / matriz se vuelven simples.

En su caso, se puede utilizar el método _.has. Ejemplo:

yourArray = {age: "10"}

_.has(yourArray, "age")

devuelve verdadero

Pero,

_.has(yourArray, "invalidKey")

devuelve falso

vatsal
fuente
15

Responder:

if ("key" in myObj)
{
    console.log("key exists!");
}
else
{
    console.log("key doesn't exist!");
}

Explicación:

El inoperador verificará si la clave existe en el objeto. Si verificó si el valor no estaba definido: if (myObj["key"] === 'undefined')podría tener problemas porque posiblemente podría existir una clave en su objeto con el undefinedvalor.

Por esa razón, es una práctica mucho mejor usar primero el inoperador y luego comparar el valor que está dentro de la clave una vez que ya sabe que existe.

Webeng
fuente
12

Aquí hay una función auxiliar que encuentro bastante útil

¡Esto keyExists(key, search)se puede usar para buscar fácilmente una clave dentro de objetos o matrices!

Simplemente páselo la clave que desea encontrar y busque obj (el objeto o matriz) en el que desea encontrarlo.

function keyExists(key, search) {
        if (!search || (search.constructor !== Array && search.constructor !== Object)) {
            return false;
        }
        for (var i = 0; i < search.length; i++) {
            if (search[i] === key) {
                return true;
            }
        }
        return key in search;
    }

// How to use it:
// Searching for keys in Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(keyExists('title', {'name': 'Jason', 'age': 29 })); // false

Ha sido bastante confiable y funciona bien entre navegadores.

jaredwilli
fuente
66
Esto parece un poco confuso: en primer lugar, al buscar una matriz, este método está buscando un valor , no una clave. En segundo lugar, ¿por qué recorrer una matriz como esta cuando puede usar el Array.indexOfmétodo incorporado ? (si buscas un valor, eso es)
Nick F
9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Si desea verificar si el objeto tiene al menos una propiedad en es2015

Object.keys(yourObjName).length : true ? false
Hajji Tarik
fuente
7

Solución ES6

usando Array#somey Object.keys. Devolverá verdadero si la clave dada existe en el objeto o falso si no existe.

var obj = {foo: 'one', bar: 'two'};
    
function isKeyInObject(obj, key) {
    var res = Object.keys(obj).some(v => v == key);
    console.log(res);
}

isKeyInObject(obj, 'foo');
isKeyInObject(obj, 'something');

Ejemplo de una línea.

console.log(Object.keys({foo: 'one', bar: 'two'}).some(v => v == 'foo'));

usuario amable
fuente
1
Fallará para las propiedades no numerables del objeto.
Sid
@Sid Dame un ejemplo.
usuario amable
Aqui tienes. let joshua = {name: 'Joshua', address: 'London'}; Object.defineProperty (joshua, 'isMarried', {valor: verdadero, enumerable: falso}); console.log ('isMarried' en Object.keys (joshua))
Sid
Estoy aplicando tu solución en mi objeto. ¿No debería ser cierto para la primera salida? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid
1
Lo siento, pero ¿verificaste la salida de la segunda declaración de la consola? Object.defineProperty es equivalente a establecer la propiedad usando notación de puntos.
Sid
6

Nosotros podemos usar - hasOwnProperty.call(obj, key);

La forma de subrayar.js :

if(_.has(this.options, 'login')){
  //key 'login' exists in this.options 
}

_.has = function(obj, key) {
  return hasOwnProperty.call(obj, key);
};
Mohan Dere
fuente
5

La forma más fácil de verificar es

"key" in object

por ejemplo:

var obj = {
  a: 1,
  b: 2,
}
"a" in obj // true
"c" in obj // false

El valor de retorno como verdadero implica que la clave existe en el objeto.

shekhardtu
fuente
4

Para aquellos que han lodashincluido en su proyecto:
hay un método lodash _.get que intenta obtener claves "profundas":

Obtiene el valor en la ruta del objeto. Si el valor resuelto no está definido, el Valor predeterminado se devuelve en su lugar.

var object = { 'a': [{ 'b': { 'c': 3 } }] };

console.log(
  _.get(object, 'a[0].b.c'),           // => 3
  _.get(object, ['a', '0', 'b', 'c']), // => 3
  _.get(object, 'a.b.c'),              // => undefined 
  _.get(object, 'a.b.c', 'default')    // => 'default'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


Esto verificará efectivamente si esa clave, por profunda que sea , esté definida y no arrojará un error que podría dañar el flujo de su programa si esa clave no está definida.

vsync
fuente
4

Si bien esto no necesariamente verifica si existe una clave, sí verifica la veracidad de un valor. Que undefinedy nullcaer debajo.

Boolean(obj.foo)

Esta solución funciona mejor para mí porque uso el mecanografiado y el uso de cadenas como esta 'foo' in objo obj.hasOwnProperty('foo') para verificar si existe una clave o no no me proporciona inteligencia.

realappie
fuente
3

Si desea verificar cualquier clave a cualquier profundidad en un objeto y tener en cuenta los valores de falsey, considere esta línea para una función de utilidad:

var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;

Resultados

var obj = {
    test: "",
    locals: {
        test: "",
        test2: false,
        test3: NaN,
        test4: 0,
        test5: undefined,
        auth: {
            user: "hw"
        }
    }
}

keyExistsOn(obj, "")
> false
keyExistsOn(obj, "locals.test")
> true
keyExistsOn(obj, "locals.test2")
> true
keyExistsOn(obj, "locals.test3")
> true
keyExistsOn(obj, "locals.test4")
> true
keyExistsOn(obj, "locals.test5")
> true
keyExistsOn(obj, "sdsdf")
false
keyExistsOn(obj, "sdsdf.rtsd")
false
keyExistsOn(obj, "sdsdf.234d")
false
keyExistsOn(obj, "2134.sdsdf.234d")
false
keyExistsOn(obj, "locals")
true
keyExistsOn(obj, "locals.")
false
keyExistsOn(obj, "locals.auth")
true
keyExistsOn(obj, "locals.autht")
false
keyExistsOn(obj, "locals.auth.")
false
keyExistsOn(obj, "locals.auth.user")
true
keyExistsOn(obj, "locals.auth.userr")
false
keyExistsOn(obj, "locals.auth.user.")
false
keyExistsOn(obj, "locals.auth.user")
true

Consulte también este paquete NPM: https://www.npmjs.com/package/has-deep-value

Alex
fuente
3
const object1 = {
  a: 'something',
  b: 'something',
  c: 'something'
};

const key = 's';

// Object.keys(object1) will return array of the object keys ['a', 'b', 'c']

Object.keys(object1).indexOf(key) === -1 ? 'the key is not there' : 'yep the key is exist';
sarea
fuente
3

En el mundo 'array' podemos ver los índices como algún tipo de claves. Lo sorprendente del inoperador (que es una buena opción para el objeto) también funciona con matrices. El valor devuelto para la clave no existente esundefined

let arr = ["a","b","c"]; // we have indexes: 0,1,2
delete arr[1];           // set 'empty' at index 1
arr.pop();               // remove last item

console.log(0 in arr,  arr[0]);
console.log(1 in arr,  arr[1]);
console.log(2 in arr,  arr[2]);

Kamil Kiełczewski
fuente
2

yourArray.indexOf (yourArrayKeyName)> -1

fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple') > -1

cierto


fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple1') > -1

falso

Anupam Maurya
fuente
0

Este ejemplo puede demostrar las diferencias entre formas diferentes. Espero que te ayude a elegir el más adecuado para tus necesidades:

// Lets create object `a` using create function `A`
function A(){};
A.prototype.onProtDef=2;
A.prototype.onProtUndef=undefined;
var a=new A();
a.ownProp = 3;
a.ownPropUndef = undefined;

// Let's try different methods:

a.onProtDef; // 2
a.onProtUndef; // undefined
a.ownProp; // 3
a.ownPropUndef; // undefined
a.whatEver; // undefined
a.valueOf; // ƒ valueOf() { [native code] }

a.hasOwnProperty('onProtDef'); // false
a.hasOwnProperty('onProtUndef'); // false
a.hasOwnProperty('ownProp'); // true
a.hasOwnProperty('ownPropUndef'); // true
a.hasOwnProperty('whatEver'); // false
a.hasOwnProperty('valueOf'); // false

'onProtDef' in a; // true
'onProtUndef' in a; // true
'ownProp' in a; // true
'ownPropUndef' in a; // true
'whatEver' in a; // false
'valueOf' in a; // true (on the prototype chain - Object.valueOf)

Object.keys(a); // ["ownProp", "ownPropUndef"]
Alejandro
fuente
-1

Nueva solución increíble con JavaScript Destructuring :

let obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
};

let {key1, key2, key3, key4} = obj;

// key1 = "value1"
// key2 = "value2"
// key3 = "value3"
// key4 = undefined

// Can easily use `if` here on key4
if(!key4) { console.log("key not present"); } // Key not present

Marque otro uso de JavaScript Destructuring

NAVIN
fuente