¿Cómo se verifica si un valor es un Objeto en JavaScript?
javascript
object
types
javascript-objects
Danny Fox
fuente
fuente

nulles un objeto).Respuestas:
ACTUALIZACIÓN :
Esta respuesta es incompleta y da resultados engañosos . Por ejemplo,
nulltambién se considera de tipoobjectJavaScript, 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
typeofes un operador, por lo que no es necesario().typeofdevuelve 'objeto' para nulo, que no es un objeto, yinstanceofno 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 !== nullmejor 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.typeofporque 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'truenullundefined¿Qué es un objeto (es decir, no un primitivo)?
Object.prototypeObject.prototypeFunction.prototypeObjectFunctionfunction C(){}- funciones definidas por el usuarioC.prototype- la propiedad prototipo de una función definida por el usuario: esto no esCes el prototipo snew C()- "nuevo" -ing una función definida por el usuarioMathArray.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
instanceofpor 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.callno 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.getPrototypeOfque arroje una excepción si su argumento no es un objeto:fuente
obj === Object(obj)devuelvetruepara matrices.var x = []; console.log(x === Object(x)); // return truegetPrototypeOfno 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]'nulltambié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
isObjectsolo funciona con literales de objeto. Si creo un tipo personalizado, creo una instancia del tipo y lofalseBoolean(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 yfalseserá devuelta. Lanullprueba 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 tienelengthatributo, 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ó.lengthpropiedad 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.lengthpropiedad (quise decir que los literales de objeto no tienenlengthatributo 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 nulles"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).
isObjectno funcionará en caso deObject.create(null)que la implementación internaObject.createse explica aquí, pero puede usarlaisObjecten 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
isDatepara suDateObject con el propósito de escribir código robusto, de lo contrario tendrá quebradizoisObjectmétodo .Dateen mi comentario fue mal elegido porque sí, la respuesta sí discuteDate. PeroDatees 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
constructorpropiedad devuelve la función con sus nombres.Introduciendo Function.name
Function.namedevuelve 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,undefinedynull), pero debe devolver cierto para todo lo demás (incluyendoNumber,BooleanyStringobjetos). Tenga en cuenta que JS no define qué objetos "host", comowindowoconsole, 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.toStringTagahora permite personalizar la salida deObject.prototype.toString.call(...), laisPlainObjectfunción anterior podría volverfalseen 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 Objectreduce 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) cuandoanyVares una función.La forma más razonable de verificar el tipo de un valor parece ser el
typeofoperador. 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.typeofsolo es confiable para los nonullprimitivos. Entonces, una forma de verificar si un valor es un objeto sería asegurar que la cadena devuelta portypeofno 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.
ObjectconstructorEl
Objectconstructor 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
Objectno 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
trydeclaraciones 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.
thisvalorLas antiguas especificaciones de ECMAScript requerían que el
thisvalor fuera un objeto. Se introdujo ECMAScript 3Function.prototype.call, que permitió llamar a una función con unthisvalor 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.createyObject.getPrototypeOfrequieren 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
trydeclaració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) yReflectmétodos (ES6) porque llaman métodos internos esenciales que pueden hacer cosas desagradables, por ejemplo, sivaluees un proxy. Por razones de seguridad, mis ejemplos solo hacen referenciavaluesin 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,Dateyfunctions son todos los objetos. Aunque,nulles un poco artificial. Por lo tanto, es mejor verificar elnullprimero, para detectar que no es nulo.Comprobación de
typeof o === 'object'garantías queoes un objeto. Sin esta comprobación, noObject.prototype.toStringtendría sentido, ya que devolvería el objeto para todo, ¡incluso paraundefinedynull! 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 sioes un objeto, un objeto derivado comoArray,Dateo afunction.En
isDerivedObjectfunción, comprueba sioes 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
prototypepara unobjectsolo 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]'nullcheque, 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 elinstanceofoperador. Eliminará nulo, pero Array tiene Objeto en la cadena de herencia.Entonces la solución es:
fuente
/./ instanceof Object //truePoco 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
_.isObjectqué 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_.isPlainObjectme permite hacer.Esto funcionará Es una función que devuelve verdadero, falso o posiblemente nulo.
fuente
nullel 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:
undefinednullbooleanstringnumberUn objeto no es un primitivo:
O alternativamente:
Prueba de cualquier matriz:
Prueba de objeto excluido:
DateRegExpBooleanNumberStringFunctioncualquier matrizfuente
Cuando todo lo demás falla, uso esto:
fuente
item.constructor === Object?nulllanza una excepciónUncaught TypeError: Cannot read property 'constructor' of null(…)indexOfo 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,documento los objetos con cadenas de prototipos más de 1 paso.En lugar de verificar
typeofnuestra 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
typeofoperador 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 variableves un objeto repitiendo esencialmente dos verificaciones:vis'[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.
vse 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 devesnull, 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
valueesnullesto arrojará un error ...falsepara el objetoObject.assign({}, {constructor: null}).Si explícitamente quiere verificar si el valor dado es
{}.fuente
!!objes una abreviatura para verificar siobjes 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, nonulles, no es typeof'function', y es unObjectfuente
trueparanew 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
instanceofpara buscar objetos. Aún así, esto no es una ciencia exacta.new Foo()devuelve unFooobjeto, igual quenew String()devuelve unStringobjeto, onew Date()devuelve unDateobjeto, se pueden hacerFoo = function(){}; isVarTypeOf(new Foo(), Foo);también