¿Cómo se verifica si un valor es un Objeto en JavaScript?
javascript
object
types
javascript-objects
Danny Fox
fuente
fuente
null
es un objeto).Respuestas:
ACTUALIZACIÓN :
Esta respuesta es incompleta y da resultados engañosos . Por ejemplo,
null
también se considera de tipoobject
JavaScript, sin mencionar otros casos extremos. Siga la recomendación a continuación y continúe con la otra "respuesta más votada (¡y correcta!)" .Respuesta original :
Intenta usar
typeof(var)
y / ovar instanceof something
.EDIT: Esta respuesta da una idea de cómo examinar las propiedades de variables, pero es no una receta a prueba de balas (después de todo, no existe una receta en absoluto!) Para comprobar si se trata de un objeto, ni mucho menos. Dado que las personas tienden a buscar algo para copiar desde aquí sin hacer ninguna investigación, recomiendo encarecidamente que recurran a la otra respuesta más votada (¡y correcta!).
fuente
typeof
es un operador, por lo que no es necesario()
.typeof
devuelve 'objeto' para nulo, que no es un objeto, yinstanceof
no funciona para objetos creados usandoObject.create(null)
.Si
typeof yourVariable === 'object'
, es un objeto o nulo. Si desea excluir nulo, simplemente hágalotypeof yourVariable === 'object' && yourVariable !== null
.fuente
yourVariable !== null
mejor práctica?typeof null == 'object'
no se solucionará en ES6 . Ellos dijeron:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
typeof
porque tiene algunos casos especiales que no necesariamente tienen mucho sentido. Si está tratando de diferenciar entre matrices y objetos que no son matrices, entonces definitivamente no desea usartypeof
.Object.prototype.toString.call(yourVar)
, siendo yourVar lo que necesita inspeccionar. En caso de matrices,Object.prototype.toString.call([1,2])
regresa[object Array]
Definamos "objeto" en Javascript . Según los documentos de MDN , cada valor es un objeto o una primitiva:
¿Qué es un primitivo?
3
'abc'
true
null
undefined
¿Qué es un objeto (es decir, no un primitivo)?
Object.prototype
Object.prototype
Function.prototype
Object
Function
function C(){}
- funciones definidas por el usuarioC.prototype
- la propiedad prototipo de una función definida por el usuario: esto no esC
es el prototipo snew C()
- "nuevo" -ing una función definida por el usuarioMath
Array.prototype
{"a": 1, "b": 2}
- objetos creados usando notación literalnew Number(3)
- envoltorios alrededor de primitivasObject.create(null)
Object.create(null)
Cómo verificar si un valor es un objeto
instanceof
por sí solo no funcionará, ya que se pierden dos casos:typeof x === 'object'
no funcionará debido a falsos positivos (null
) y falsos negativos (funciones):Object.prototype.toString.call
no funcionará, debido a falsos positivos para todas las primitivas:Entonces uso:
La respuesta de @ Daan también parece funcionar:
porque, según los documentos de MDN :
Una tercera forma que parece funcionar (no estoy seguro si es 100%) es usar
Object.getPrototypeOf
que arroje una excepción si su argumento no es un objeto:fuente
obj === Object(obj)
devuelvetrue
para matrices.var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
no funciona, por ejemplo, con proxys revocados, que son objetos pero arrojan.({}).toString.apply(obj) === '[object Object]'
esto distingue entre matrices y objetos que no son matrices?underscore.js proporciona el siguiente método para averiguar si algo es realmente un objeto:
ACTUALIZAR
Debido a un error anterior en V8 y una pequeña optimización de micro velocidad, el método tiene el siguiente aspecto desde underscore.js 1.7.0 (agosto de 2014):
fuente
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
también. Debería ser la respuesta aceptada.Object.prototype.toString.call(myVar)
volverá:"[object Object]"
si myVar es un objeto"[object Array]"
si myVar es una matrizPara obtener más información sobre esto y por qué es una buena alternativa a typeof, consulte este artículo .
fuente
typeof [] === 'object'
->true
. Eso es lo que necesitas este método.Object.prototype.toString.call(3)
->"[object Number]"
.Object.prototype.toString.call(new Number(3))
->"[object Number]
"getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Para verificar simplemente contra Object o Array sin función adicional llamada (velocidad). Como también publicado aquí .
isArray ()
isObject () - Nota: use solo para literales de objetos, ya que devuelve falso para objetos personalizados, como nueva fecha o nuevo YourCustomObject.
fuente
isObject
solo funciona con literales de objeto. Si creo un tipo personalizado, creo una instancia del tipo y lofalse
Boolean(a)
es más largo, pero mucho más intuitivo. Simplemente no usenew Boolean(a)
: ( aquí está el por qué )!{
personaje? Para el caso de la matriz, siempre que no necesite admitir IE <9, puede usarArray.isArray()
para determinar si algo es una matriz. Pasa todos los casos de prueba que proporcionó.Me gusta simplemente:
Si el elemento es un objeto JS, y no es una matriz JS, y no es
null
... si los tres demuestran ser verdaderos, regresetrue
. Si alguna de las tres condiciones falla, la&&
prueba hará un cortocircuito yfalse
será devuelta. Lanull
prueba se puede omitir si lo desea (dependiendo de cómo usenull
).DOCS:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
http://devdocs.io/javascript/global_objects/array/isarray
http://devdocs.io/javascript/global_objects/null
fuente
new Date()
devuelve un objeto. Una matriz es, desde un punto de vista lógico, no un objeto, aunque JavaScript los maneja e informa como tal. Sin embargo, en la práctica, no es útil verlos iguales, porque no lo son. Un objeto no tienelength
atributo, por ejemplo, y no tiene métodos como push (). Y a veces es posible que desee asignar parámetros a una función sobrecargada, donde debe marcar la diferencia entre una matriz o un objeto, especialmente si otros parámetros dependen de cuál se proporcionó.length
propiedad ni métodos comopush
,Object.create(Array.prototype)
es un contraejemplo trivial de un objeto sin matriz que los tiene. Lo que hace que las matrices sean especiales es que son objetos exóticos con un método interno esencial personalizado [[DefineOwnProperty]], pero siguen siendo objetos.length
propiedad (quise decir que los literales de objeto no tienenlength
atributo por defecto). Escribí que las matrices no son objetos desde un punto de vista lógico . Estoy hablando de la lógica del programa. A veces es necesario verificar si una matriz es una matriz "real" y definitivamente no es un objeto "real". Para esoArray.isArray()
es eso . Imagine que tiene una función que acepta un objeto o una matriz de objetos. Buscar un atributo o método especial es una solución sucia. La forma nativa siempre es mejor.typeof null
es"object"
no"undefined"
.Con función
Array.isArray
:Sin función
Array.isArray
:Me sorprendió la cantidad de votos a favor de las respuestas incorrectas 😮 ¡¡¡¡¡
Solo 1 respuesta pasó mis exámenes !!! Aquí he creado mi versión simplificada:
En cuanto a mí, es claro y simple, ¡y simplemente funciona! Aquí mis pruebas:
UNA VEZ MÁS: ¡no todas las respuestas pasan esta prueba! 🙈
En caso de que necesite verificar que el objeto es una instancia de una clase particular, debe verificar el constructor con su clase particular, como:
prueba simple:
Como resultado, tendrá un código estricto y robusto.
En caso de que no va a crear funciones como
isDate
,isError
,isRegExp
, etc usted puede considerar la opción de utilizar estas funciones generalizadas:no funcionará correctamente para todos los casos de prueba mencionados anteriormente, pero es lo suficientemente bueno para todos los objetos (simples o construidos).
isObject
no funcionará en caso deObject.create(null)
que la implementación internaObject.create
se explica aquí, pero puede usarlaisObject
en una implementación más sofisticada:¡Ya hay un paquete creado en npm v1 basado en esta implementación! ¡Y funciona para todos los casos de prueba descritos anteriormente! 🙂
fuente
isDate
para suDateObject con el propósito de escribir código robusto, de lo contrario tendrá quebradizoisObject
método .Date
en mi comentario fue mal elegido porque sí, la respuesta sí discuteDate
. PeroDate
es solo una de las infinitas clases posibles y el punto es válido para cualquier otra clase. Ejemplo:class Foo() { }; var x = new Foo(); isObject(x)
devolucionesfalse
. No sé exactamente cuál es el caso de uso del OP, pero es fácil concebir escenarios en los que no sea factible tener que conocer todas las clases posibles y verificar específicamente cada una de ellas .¡Oh Dios mío! Creo que esto podría ser más corto que nunca, veamos esto:
Código corto y final
Explicado
Tipos de retorno
tipo de objetos JavaScript (incluidos
null
) devuelve"object"
Comprobando sus constructores
Comprobar en su
constructor
propiedad devuelve la función con sus nombres.Introduciendo Function.name
Function.name
devuelve un nombre de solo lectura de una función o"anonymous"
para cierres.fuente
Object.create(null)
y por qué lo harías de todos modos ...?OK, vamos a darle este concepto primero antes de responder a su pregunta, en funciones de JavaScript son objetos, también nula, de objetos, matrices y hasta la fecha, a fin de que se ve allí es no de una manera tan simple como typeof obj === 'objeto', por lo todo lo mencionado anteriormente devolverá verdadero , pero hay formas de verificarlo escribiendo una función o usando marcos JavaScript, OK:
Ahora, imagine que tiene este objeto que es un objeto real (no nulo, función o matriz):
JavaScript puro:
o
o
o
Simplemente puede usar una de estas funciones como se indica arriba en su código llamándolas y devolverá verdadero si es un objeto:
Si está utilizando un marco de JavaScript, generalmente han preparado este tipo de funciones para usted, estas son algunas de ellas:
jQuery:
Angular:
Subrayar y Lodash:
fuente
Depende de lo que quieras decir con "es un objeto". Si desea todo lo que no es primitivo , es decir, cosas en las que puede establecer nuevas propiedades, esto debería ser el truco:
Excluye las primitivas (números de civil /
NaN
/Infinity
, las cadenas de fricción, símbolos,true
/false
,undefined
ynull
), pero debe devolver cierto para todo lo demás (incluyendoNumber
,Boolean
yString
objetos). Tenga en cuenta que JS no define qué objetos "host", comowindow
oconsole
, deberían devolver cuando se usa contypeof
, por lo que es difícil cubrirlos con un cheque como este.Si desea saber si algo es un objeto "simple", es decir, se creó como literal
{}
o conObject.create(null)
, puede hacer esto:Editar 2018 : como
Symbol.toStringTag
ahora permite personalizar la salida deObject.prototype.toString.call(...)
, laisPlainObject
función anterior podría volverfalse
en algunos casos incluso cuando el objeto comenzó su vida como un literal. Podría decirse que, por convención, un objeto con una etiqueta de cadena personalizada ya no es exactamente un objeto simple, pero esto ha enturbiado aún más la definición de qué es un objeto simple en Javascript.fuente
instanceof Object
, dos literales de función idénticos no son estrictamente iguales, se pasan por referencia, etc.Dios mío, demasiada confusión en otras respuestas.
Respuesta corta
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Para probar esto, simplemente ejecute las siguientes declaraciones en la consola de Chrome.
Caso 1.
Caso 2.
Caso 3.
Explicación
Ok, vamos a descomponerlo
typeof anyVar == 'object'
se devuelve verdadero de tres candidatos:[], {} and null
,anyVar instanceof Object
reduce estos candidatos a dos:[], {}
!(anyVar instanceof Array)
se reduce a uno solo{}
¡Tambores por favor!
Con esto, es posible que ya haya aprendido cómo verificar la matriz en Javascript.
fuente
false
(como se desee) cuandoanyVar
es una función.La forma más razonable de verificar el tipo de un valor parece ser el
typeof
operador. El único problema es que está horriblemente roto:"object"
pornull
, que pertenece al tipo nulo."function"
objetos invocables, que pertenecen al tipo de objeto."unknown"
. Los únicos resultados prohibidos son"function"
los tipos primitivos.typeof
solo es confiable para los nonull
primitivos. Entonces, una forma de verificar si un valor es un objeto sería asegurar que la cadena devuelta portypeof
no corresponda a una primitiva, y que el objeto no lo seanull
. Sin embargo, el problema es que un estándar futuro podría introducir un nuevo tipo primitivo, y nuestro código lo consideraría un objeto. Los nuevos tipos no aparecen con frecuencia, pero por ejemplo ECMAScript 6 introdujo el tipo de símbolo.Por lo tanto, en lugar de
typeof
, solo recomiendo enfoques cuyo resultado varía dependiendo de si el valor es un objeto o no. Lo siguiente pretende ser unLista exhaustiva pero no exhaustiva de formas adecuadas de probar si un valor pertenece al tipo de objeto.
Object
constructorEl
Object
constructor coacciona el argumento pasado a un objeto. Si ya es un objeto, se devuelve el mismo objeto.Por lo tanto, puede usarlo para forzar el valor de un objeto y comparar estrictamente ese objeto con el valor original.
La siguiente función requiere ECMAScript 3, que introdujo
===
:Me gusta este enfoque porque es simple y autodescriptivo, y una verificación análoga también funcionará para booleanos, números y cadenas. Sin embargo, tenga en cuenta que se basa en que lo global
Object
no se oculta ni se modifica.Constructores
Cuando crea una instancia de un constructor, puede devolver un valor diferente de la instancia recién creada. Pero ese valor será ignorado a menos que sea un objeto.
La siguiente función requiere ECMAScript 3, que permitió a los constructores devolver objetos que no son. Antes de ECMAScript 3 que arrojó un error, pero las
try
declaraciones no existían en ese entonces.Si bien es un poco menos simple que el ejemplo anterior, este no se basa en ninguna propiedad global y, por lo tanto, podría ser el más seguro.
this
valorLas antiguas especificaciones de ECMAScript requerían que el
this
valor fuera un objeto. Se introdujo ECMAScript 3Function.prototype.call
, que permitió llamar a una función con unthis
valor arbitrario , pero forzado a un objeto.ECMAScript 5 introdujo un modo estricto que eliminó este comportamiento, pero en modo descuidado todavía podemos (pero posiblemente no deberíamos) confiar en él.
[[Prototipo]]
Todos los objetos ordinarios tienen una ranura interna llamada [[Prototipo]], cuyo valor determina de qué otro objeto hereda. El valor solo puede ser un objeto o
null
. Por lo tanto, puede intentar crear un objeto que herede del valor deseado y verificar si funcionó.Ambos
Object.create
yObject.getPrototypeOf
requieren ECMAScript 5.Algunas nuevas formas de ECMAScript 6
ECMAScript 6 presenta algunas nuevas formas indirectas de verificar si un valor es un objeto. Utilizan el enfoque visto anteriormente para pasar el valor a algún código que requiere un objeto, envuelto dentro de una
try
declaración para detectar errores. Algunos ejemplos ocultos, no vale la pena comentarMostrar fragmento de código
Mostrar fragmento de código
Nota: intencionalmente omití algunos enfoques como
Object.getPrototypeOf(value)
(ES5) yReflect
métodos (ES6) porque llaman métodos internos esenciales que pueden hacer cosas desagradables, por ejemplo, sivalue
es un proxy. Por razones de seguridad, mis ejemplos solo hacen referenciavalue
sin acceder directamente.fuente
Prueba esto
fuente
Object.prototype instanceof Object
-> falso.Object.create(null) instanceof Object
-> falso.new Date() instanceof Object
=> verdaderoFunciones listas para usar para verificar
Explicación
En Javascript,
null
,Object
,Array
,Date
yfunction
s son todos los objetos. Aunque,null
es un poco artificial. Por lo tanto, es mejor verificar elnull
primero, para detectar que no es nulo.Comprobación de
typeof o === 'object'
garantías queo
es un objeto. Sin esta comprobación, noObject.prototype.toString
tendría sentido, ya que devolvería el objeto para todo, ¡incluso paraundefined
ynull
! Por ejemplo:toString(undefined)
vuelve[object Undefined]
!Después de la
typeof o === 'object'
verificación, toString.call (o) es un excelente método para verificar sio
es un objeto, un objeto derivado comoArray
,Date
o afunction
.En
isDerivedObject
función, comprueba sio
es una función. Porque, también funciona un objeto, por eso está ahí. Si no lo hizo, la función volverá como falsa. Ejemplo:isDerivedObject(function() {})
volveríafalse
, pero ahora vuelvetrue
.Siempre se puede cambiar la definición de lo que es un objeto. Entonces, uno puede cambiar estas funciones en consecuencia.
Pruebas
fuente
Si desea comprobar si el
prototype
para unobject
solo provieneObject
. FiltraString
,Number
,Array
,Arguments
, etc.O como una función de flecha de expresión única (ES6 +)
fuente
return Object.prototype.toString.call(n) === '[object Object]'
null
cheque, porqueObject.prototype.toString.call(null) === '[object Null]'
Me pidieron que proporcionara más detalles. La forma más limpia y comprensible de verificar si nuestra variable es un objeto es
typeof myVar
. Devuelve una cadena con un tipo (por ejemplo"object"
,"undefined"
).Desafortunadamente, Array y null también tienen un tipo
object
. Para tomar solo objetos reales, es necesario verificar la cadena de herencia utilizando elinstanceof
operador. Eliminará nulo, pero Array tiene Objeto en la cadena de herencia.Entonces la solución es:
fuente
/./ instanceof Object //true
Poco tarde ... para "objetos simples" (quiero decir, como {'x': 5, 'y': 7}) tengo este pequeño fragmento:
Genera el siguiente resultado:
Siempre funciona para mi. If devolverá "verdadero" solo si el tipo de "o" es "objeto", pero no nulo, o matriz, o función. :)
fuente
lodash tiene isPlainObject , que podría ser lo que buscan muchos de los que vienen a esta página. Devuelve falso cuando da una función o matriz.
fuente
_.isObject
qué coincide con lo que JS considera un objeto. Pero lo que generalmente necesito es diferenciar, por ejemplo, un objeto literal y una matriz, que es exactamente lo que_.isPlainObject
me permite hacer.Esto funcionará Es una función que devuelve verdadero, falso o posiblemente nulo.
fuente
null
el resultado de la prueba final en lugar de hacerlofalse
. Consulte ¿ Cuándo debo hacer modificaciones al código?Dado que parece haber mucha confusión sobre cómo manejar este problema correctamente, dejaré mis 2 centavos (esta respuesta cumple con las especificaciones y produce resultados correctos en todas las circunstancias):
Prueba de primitivas:
undefined
null
boolean
string
number
Un objeto no es un primitivo:
O alternativamente:
Prueba de cualquier matriz:
Prueba de objeto excluido:
Date
RegExp
Boolean
Number
String
Function
cualquier matrizfuente
Cuando todo lo demás falla, uso esto:
fuente
item.constructor === Object
?null
lanza una excepciónUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
o por elconstructor.name
?La biblioteca funcional Ramda tiene una función maravillosa para detectar tipos de JavaScript.
Parafraseando la función completa :
Tuve que reír cuando me di cuenta de lo simple y hermosa que era la solución.
Ejemplo de uso de la documentación de Ramda :
fuente
Después de leer y probar una gran cantidad de implementaciones, me he dado cuenta de que muy pocas personas tratan de comprobar si hay valores como
JSON
,Math
,document
o los objetos con cadenas de prototipos más de 1 paso.En lugar de verificar
typeof
nuestra variable y luego eliminar los casos límite, pensé que sería mejor si la verificación se mantuviera lo más simple posible para evitar tener que refactorizar cuando hay nuevas primitivas u objetos nativos agregados que se registran comotypeof
'objeto '.Después de todo, el
typeof
operador le dirá si algo es un objeto para JavaScript , pero la definición de JavaScript de un objeto es demasiado amplia para la mayoría de los escenarios del mundo real (por ejemplotypeof null === 'object'
). A continuación se muestra una función que determina si la variablev
es un objeto repitiendo esencialmente dos verificaciones:v
is'[object Object]'
.Quería que el resultado de la función fuera exactamente como los registros a continuación, así que este es el único criterio de "objetividad" con el que terminé. Si falla, la función devuelve falso de inmediato.
v
se reemplaza con el próximo prototipo en la cadena conv = Object.getPrototypeOf(v)
, pero también se evalúa directamente después. Cuando el nuevo valor dev
esnull
, significa que cada prototipo, incluido el prototipo raíz (que bien podría haber sido el único prototipo dentro de la cadena) ha pasado la verificación en el ciclo while y podemos devolver verdadero. De lo contrario, comienza una nueva iteración.fuente
fuente
value
esnull
esto arrojará un error ...false
para el objetoObject.assign({}, {constructor: null})
.Si explícitamente quiere verificar si el valor dado es
{}
.fuente
!!obj
es una abreviatura para verificar siobj
es verdad (para filtrarnull
)fuente
Es una vieja pregunta, pero pensé dejar esto aquí. La mayoría de las personas están verificando si la variable
{}
significa un valor clave emparejado y no cuál es la construcción de subrayado que JavaScript está usando para una cosa dada, porque para ser honesto, casi todo en JavaScript es un objeto. Así que quitando eso del camino. Si lo haces...La mayoría de las veces lo que queremos es saber si tenemos un objeto de recurso de una API o nuestra llamada a la base de datos devuelta desde el ORM. Entonces podemos probar si no es un
Array
, nonull
es, no es typeof'function'
, y es unObject
fuente
true
paranew Date()
new Date()
Lo que me gusta usar es esto
Creo que en la mayoría de los casos, una fecha debe pasar el cheque como un objeto, por lo que no filtro las fechas
fuente
Encontré una "nueva" forma de hacer este tipo de comprobación de tipo a partir de esta pregunta SO: ¿Por qué la instancia de devuelve falso para algunos literales?
a partir de eso, creé una función para la verificación de tipos de la siguiente manera:
entonces solo puedes hacer:
Esto se prueba en Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43
editar:
si también desea verificar si una variable es nula o indefinida, puede usar esto en su lugar:
actualización del comentario de inanc: desafío aceptado: D
si quieres perder objetos de comparación puedes intentarlo de esta manera:
de esa manera, puedes hacer como el comentario de inanc:
o
fuente
instanceof
para buscar objetos. Aún así, esto no es una ciencia exacta.new Foo()
devuelve unFoo
objeto, igual quenew String()
devuelve unString
objeto, onew Date()
devuelve unDate
objeto, se pueden hacerFoo = function(){}; isVarTypeOf(new Foo(), Foo);
también