¿Cómo se verifica si un valor es un Objeto en JavaScript?
¿Cómo se verifica si un valor es un Objeto en JavaScript?
Respuestas:
ACTUALIZACIÓN :
Esta respuesta es incompleta y da resultados engañosos . Por ejemplo,null
también se considera de tipo object
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 / o var 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!).
typeof
es un operador, por lo que no es necesario ()
.
typeof
devuelve 'objeto' para nulo, que no es un objeto, y instanceof
no funciona para objetos creados usando Object.create(null)
.
Si typeof yourVariable === 'object'
, es un objeto o nulo. Si desea excluir nulo, simplemente hágalo typeof yourVariable === 'object' && yourVariable !== null
.
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 usar typeof
.
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:
primitivo, valor primitivo
Un dato que no es un objeto y no tiene ningún método. JavaScript tiene 5 tipos de datos primitivos: cadena, número, booleano, nulo, indefinido.
¿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 es C
es el prototipo s
new 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:
// oops: isObject(Object.prototype) -> false
// oops: isObject(Object.create(null)) -> false
function isObject(val) {
return val instanceof Object;
}
typeof x === 'object'
no funcionará debido a falsos positivos ( null
) y falsos negativos (funciones):
// oops: isObject(Object) -> false
function isObject(val) {
return (typeof val === 'object');
}
Object.prototype.toString.call
no funcionará, debido a falsos positivos para todas las primitivas:
> Object.prototype.toString.call(3)
"[object Number]"
> Object.prototype.toString.call(new Number(3))
"[object Number]"
Entonces uso:
function isObject(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
La respuesta de @ Daan también parece funcionar:
function isObject(obj) {
return obj === Object(obj);
}
porque, según los documentos de MDN :
El constructor de objetos crea un contenedor de objetos para el valor dado. Si el valor es nulo o indefinido, creará y devolverá un objeto vacío; de lo contrario, devolverá un objeto de un tipo que corresponde al valor dado. Si el valor ya es un objeto, devolverá el valor.
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:
// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)
// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})
obj === Object(obj)
devuelve true
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:
_.isObject = function(obj) {
return obj === Object(obj);
};
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):
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
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 .
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 ()
isArray = function(a) {
return (!!a) && (a.constructor === Array);
};
console.log(isArray( )); // false
console.log(isArray( null)); // false
console.log(isArray( true)); // false
console.log(isArray( 1)); // false
console.log(isArray( 'str')); // false
console.log(isArray( {})); // false
console.log(isArray(new Date)); // false
console.log(isArray( [])); // true
isObject () - Nota: use solo para literales de objetos, ya que devuelve falso para objetos personalizados, como nueva fecha o nuevo YourCustomObject.
isObject = function(a) {
return (!!a) && (a.constructor === Object);
};
console.log(isObject( )); // false
console.log(isObject( null)); // false
console.log(isObject( true)); // false
console.log(isObject( 1)); // false
console.log(isObject( 'str')); // false
console.log(isObject( [])); // false
console.log(isObject(new Date)); // false
console.log(isObject( {})); // true
isObject
solo funciona con literales de objeto. Si creo un tipo personalizado, creo una instancia del tipo y lo false
Boolean(a)
es más largo, pero mucho más intuitivo. Simplemente no use new Boolean(a)
: ( aquí está el por qué )!
{
personaje? Para el caso de la matriz, siempre que no necesite admitir IE <9, puede usar Array.isArray()
para determinar si algo es una matriz. Pasa todos los casos de prueba que proporcionó.
Me gusta simplemente:
function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null);
}
Si el elemento es un objeto JS, y no es una matriz JS, y no es null
... si los tres demuestran ser verdaderos, regrese true
. Si alguna de las tres condiciones falla, la &&
prueba hará un cortocircuito y false
será devuelta. La null
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
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 tiene length
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 como push
, 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 tienen length
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 eso Array.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"
.
Array.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
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:
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}
En cuanto a mí, es claro y simple, ¡y simplemente funciona! Aquí mis pruebas:
console.log(isObject({})); // Will return: true
console.log(isObject([])); // Will return: false
console.log(isObject(null)); // Will return: false
console.log(isObject(/.*/)); // Will return: false
console.log(isObject(function () {})); // Will return: false
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:
function isDate(o) {
return o instanceof Object && o.constructor === Date;
}
prueba simple:
var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d)); // Will return: true
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:
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
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 de Object.create(null)
que la implementación interna Object.create
se explica aquí, pero puede usarla isObject
en una implementación más sofisticada:
function isObject(o, strict = true) {
if (o === null || o === undefined) {
return false;
}
const instanceOfObject = o instanceof Object;
const typeOfObject = typeof o === 'object';
const constructorUndefined = o.constructor === undefined;
const constructorObject = o.constructor === Object;
const typeOfConstructorObject = typeof o.constructor === 'function';
let r;
if (strict === true) {
r = (instanceOfObject || typeOfObject) && (constructorUndefined || constructorObject);
} else {
r = (constructorUndefined || typeOfConstructorObject);
}
return r;
};
¡Ya hay un paquete creado en npm v1 basado en esta implementación! ¡Y funciona para todos los casos de prueba descritos anteriormente! 🙂
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í discute Date
. Pero Date
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)
devoluciones false
. 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:
function isObject(obj)
{
return obj != null && obj.constructor.name === "Object"
}
console.log(isObject({})) // returns true
console.log(isObject([])) // returns false
console.log(isObject(null)) // returns false
tipo de objetos JavaScript (incluidos null
) devuelve"object"
console.log(typeof null, typeof [], typeof {})
Comprobar en su constructor
propiedad devuelve la función con sus nombres.
console.log(({}).constructor) // returns a function with name "Object"
console.log(([]).constructor) // returns a function with name "Array"
console.log((null).constructor) //throws an error because null does not actually have a property
Function.name
devuelve un nombre de solo lectura de una función o "anonymous"
para cierres.
console.log(({}).constructor.name) // returns "Object"
console.log(([]).constructor.name) // returns "Array"
console.log((null).constructor.name) //throws an error because null does not actually have a property
Nota: A partir de 2018, Function.name podría no funcionar en IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility
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):
var obj = {obj1: 'obj1', obj2: 'obj2'};
JavaScript puro:
//that's how it gets checked in angular framework
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
o
//make sure the second object is capitalised
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
o
function isObject(obj) {
return obj.constructor.toString().indexOf("Object") > -1;
}
o
function isObject(obj) {
return obj instanceof Object;
}
Simplemente puede usar una de estas funciones como se indica arriba en su código llamándolas y devolverá verdadero si es un objeto:
isObject(obj);
Si está utilizando un marco de JavaScript, generalmente han preparado este tipo de funciones para usted, estas son algunas de ellas:
jQuery:
//It returns 'object' if real Object;
jQuery.type(obj);
Angular:
angular.isObject(obj);
Subrayar y Lodash:
//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);
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:
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
Excluye las primitivas (números de civil / NaN
/ Infinity
, las cadenas de fricción, símbolos, true
/ false
, undefined
y null
), pero debe devolver cierto para todo lo demás (incluyendo Number
, Boolean
y String
objetos). Tenga en cuenta que JS no define qué objetos "host", como window
o console
, 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 con Object.create(null)
, puede hacer esto:
function isPlainObject(value) {
if (Object.prototype.toString.call(value) !== '[object Object]') {
return false;
} else {
var prototype = Object.getPrototypeOf(value);
return prototype === null || prototype === Object.prototype;
}
}
Editar 2018 : como Symbol.toStringTag
ahora permite personalizar la salida de Object.prototype.toString.call(...)
, la isPlainObject
función anterior podría volver false
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.
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.
var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true
Caso 2.
anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false
Caso 3.
anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false
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.
false
(como se desee) cuando anyVar
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 no null
primitivos. Entonces, una forma de verificar si un valor es un objeto sería asegurar que la cadena devuelta por typeof
no corresponda a una primitiva, y que el objeto no lo sea null
. 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 un
Object
constructor
El 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 ===
:
function isObject(value) { /* Requires ECMAScript 3 or later */
return Object(value) === value;
}
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.
function isObject(value) { /* Requires ECMAScript 3 or later */
return new function() { return value; }() === value;
}
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
valor
Las antiguas especificaciones de ECMAScript requerían que el this
valor fuera un objeto. Se introdujo ECMAScript 3 Function.prototype.call
, que permitió llamar a una función con un this
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.
function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
return function() { return this === value; }.call(value);
}
[[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
y Object.getPrototypeOf
requieren ECMAScript 5.
function isObject(value) { /* Requires ECMAScript 5 or later */
try {
Object.create(value);
return value !== null;
} catch(err) {
return false;
}
}
function isObject(value) { /* Requires ECMAScript 5 or later */
function Constructor() {}
Constructor.prototype = value;
return Object.getPrototypeOf(new Constructor()) === value;
}
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 comentar
Nota: intencionalmente omití algunos enfoques como Object.getPrototypeOf(value)
(ES5) y Reflect
métodos (ES6) porque llaman métodos internos esenciales que pueden hacer cosas desagradables, por ejemplo, si value
es un proxy. Por razones de seguridad, mis ejemplos solo hacen referencia value
sin acceder directamente.
Prueba esto
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Object.prototype instanceof Object
-> falso. Object.create(null) instanceof Object
-> falso.
new Date() instanceof Object
=> verdadero
function isObject(o) {
return null != o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]';
}
function isDerivedObject(o) {
return !isObject(o) &&
null != o &&
(typeof o === 'object' || typeof o === 'function') &&
/^\[object /.test(Object.prototype.toString.call(o));
}
// Loose equality operator (==) is intentionally used to check
// for undefined too
// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null
En Javascript, null
, Object
, Array
, Date
y function
s son todos los objetos. Aunque, null
es un poco artificial. Por lo tanto, es mejor verificar el null
primero, para detectar que no es nulo.
Comprobación de typeof o === 'object'
garantías que o
es un objeto. Sin esta comprobación, no Object.prototype.toString
tendría sentido, ya que devolvería el objeto para todo, ¡incluso para undefined
y null
! 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 si o
es un objeto, un objeto derivado como Array
, Date
o a function
.
En isDerivedObject
función, comprueba si o
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ía false
, pero ahora vuelve true
.
Siempre se puede cambiar la definición de lo que es un objeto. Entonces, uno puede cambiar estas funciones en consecuencia.
function isObject(o) {
return null != o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]';
}
function isDerivedObject(o) {
return !isObject(o) &&
null != o &&
(typeof o === 'object' || typeof o === 'function') &&
/^\[object /.test(Object.prototype.toString.call(o));
}
// TESTS
// is null an object?
console.log(
'is null an object?', isObject(null)
);
console.log(
'is null a derived object?', isDerivedObject(null)
);
// is 1234 an object?
console.log(
'is 1234 an object?', isObject(1234)
);
console.log(
'is 1234 a derived object?', isDerivedObject(1234)
);
// is new Number(1234) an object?
console.log(
'is new Number(1234) an object?', isObject(new Number(1234))
);
console.log(
'is new Number(1234) a derived object?', isDerivedObject(1234)
);
// is function object an object?
console.log(
'is (new (function (){})) an object?',
isObject((new (function (){})))
);
console.log(
'is (new (function (){})) a derived object?',
isObject((new (function (){})))
);
// is {} an object?
console.log(
'is {} an object?', isObject({})
);
console.log(
'is {} a derived object?', isDerivedObject({})
);
// is Array an object?
console.log(
'is Array an object?',
isObject([])
)
console.log(
'is Array a derived object?',
isDerivedObject([])
)
// is Date an object?
console.log(
'is Date an object?', isObject(new Date())
);
console.log(
'is Date a derived object?', isDerivedObject(new Date())
);
// is function an object?
console.log(
'is function an object?', isObject(function(){})
);
console.log(
'is function a derived object?', isDerivedObject(function(){})
);
Si desea comprobar si el prototype
para un object
solo proviene Object
. Filtra String
, Number
, Array
, Arguments
, etc.
function isObject (n) {
return Object.prototype.toString.call(n) === '[object Object]';
}
O como una función de flecha de expresión única (ES6 +)
const isObject = n => Object.prototype.toString.call(n) === '[object Object]'
return Object.prototype.toString.call(n) === '[object Object]'
null
cheque, porqueObject.prototype.toString.call(null) === '[object Null]'
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true
var b ={a: 1}
b instanceof Object //true
b instanceof Array //false
var c = null
c instanceof Object //false
c instanceof Array //false
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 el instanceof
operador. Eliminará nulo, pero Array tiene Objeto en la cadena de herencia.
Entonces la solución es:
if (myVar instanceof Object && !(myVar instanceof Array)) {
// code for objects
}
/./ instanceof Object //true
Poco tarde ... para "objetos simples" (quiero decir, como {'x': 5, 'y': 7}) tengo este pequeño fragmento:
function isPlainObject(o) {
return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
false
:(typeof o == 'object');
}
Genera el siguiente resultado:
console.debug(isPlainObject(isPlainObject)); //function, false
console.debug(isPlainObject({'x': 6, 'y': 16})); //literal object, true
console.debug(isPlainObject(5)); //number, false
console.debug(isPlainObject(undefined)); //undefined, false
console.debug(isPlainObject(null)); //null, false
console.debug(isPlainObject('a')); //string, false
console.debug(isPlainObject([])); //array?, false
console.debug(isPlainObject(true)); //bool, false
console.debug(isPlainObject(false)); //bool, false
Siempre funciona para mi. If devolverá "verdadero" solo si el tipo de "o" es "objeto", pero no nulo, o matriz, o función. :)
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.
_.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.
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null
null
el resultado de la prueba final en lugar de hacerlo false
. 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
function isPrimitive(o){return typeof o!=='object'||null}
Un objeto no es un primitivo:
function isObject(o){return !isPrimitive(o)}
O alternativamente:
function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}
Prueba de cualquier matriz:
const isArray=(function(){
const arrayTypes=Object.create(null);
arrayTypes['Array']=true;
arrayTypes['Int8Array']=true;
arrayTypes['Uint8Array']=true;
arrayTypes['Uint8ClampedArray']=true;
arrayTypes['Int16Array']=true;
arrayTypes['Uint16Array']=true;
arrayTypes['Int32Array']=true;
arrayTypes['Uint32Array']=true;
arrayTypes['BigInt64Array']=true;
arrayTypes['BigUint64Array']=true;
arrayTypes['Float32Array']=true;
arrayTypes['Float64Array']=true;
return function(o){
if (!o) return false;
return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
}
}());
Prueba de objeto excluido: Date
RegExp
Boolean
Number
String
Function
cualquier matriz
const isObjectStrict=(function(){
const nativeTypes=Object.create(null);
nativeTypes['Date']=true;
nativeTypes['RegExp']=true;
nativeTypes['Boolean']=true;
nativeTypes['Number']=true;
nativeTypes['String']=true;
nativeTypes['Function']=true;
return function(o){
if (!o) return false;
return !isPrimitive(o)&&!isArray(o)&&!nativeTypes[o.constructor.name];
}
}());
Cuando todo lo demás falla, uso esto:
var isObject = function(item) {
return item.constructor.name === "Object";
};
item.constructor === Object
?
null
lanza una excepciónUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
o por el constructor.name
?
La biblioteca funcional Ramda tiene una función maravillosa para detectar tipos de JavaScript.
Parafraseando la función completa :
function type(val) {
return val === null ? 'Null' :
val === undefined ? 'Undefined' :
Object.prototype.toString.call(val).slice(8, -1);
}
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 :
R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"
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 ejemplo typeof null === 'object'
). A continuación se muestra una función que determina si la variable v
es un objeto repitiendo esencialmente dos verificaciones:
v
is '[object Object]'
. v
se reemplaza con el próximo prototipo en la cadena con v = Object.getPrototypeOf(v)
, pero también se evalúa directamente después. Cuando el nuevo valor de v
es null
, 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.function isObj (v) {
while ( Object.prototype.toString.call(v) === '[object Object]')
if ((v = Object.getPrototypeOf(v)) === null)
return true
return false
}
console.log('FALSE:')
console.log('[] -> ', isObj([]))
console.log('null -> ', isObj(null))
console.log('document -> ', isObj(document))
console.log('JSON -> ', isObj(JSON))
console.log('function -> ', isObj(function () {}))
console.log('new Date() -> ', isObj(new Date()))
console.log('RegExp -> ', isObj(/./))
console.log('TRUE:')
console.log('{} -> ', isObj({}))
console.log('new Object() -> ', isObj(new Object()))
console.log('new Object(null) -> ', isObj(new Object(null)))
console.log('new Object({}) -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype -> ', isObj(Object.prototype))
console.log('Object.create(null) -> ', isObj(Object.create(null)))
console.log('Object.create({}) -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance -> ', isObj(Object.create(Object.create({foo: 'bar'}))))
if(typeof value === 'object' && value.constructor === Object)
{
console.log("This is an object");
}
value
es null
esto arrojará un error ...
false
para el objeto Object.assign({}, {constructor: null})
.
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...
let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true
// also
x = null
typeof null // 'object'
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
, no null
es, no es typeof 'function'
, y es unObject
// To account also for new Date() as @toddmo pointed out
x instanceof Object && x.constructor === Object
x = 'test' // false
x = 3 // false
x = 45.6 // false
x = undefiend // false
x = 'undefiend' // false
x = null // false
x = function(){} // false
x = [1, 2] // false
x = new Date() // false
x = {} // true
true
paranew Date()
new Date()
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:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return false; //fallback for null or undefined
}
}
entonces solo puedes hacer:
console.log(isVarTypeOf('asdf', String)); // returns true
console.log(isVarTypeOf(new String('asdf'), String)); // returns true
console.log(isVarTypeOf(123, String)); // returns false
console.log(isVarTypeOf(123, Number)); // returns true
console.log(isVarTypeOf(new Date(), String)); // returns false
console.log(isVarTypeOf(new Date(), Number)); // returns false
console.log(isVarTypeOf(new Date(), Date)); // returns true
console.log(isVarTypeOf([], Object)); // returns false
console.log(isVarTypeOf([], Array)); // returns true
console.log(isVarTypeOf({}, Object)); // returns true
console.log(isVarTypeOf({}, Array)); // returns false
console.log(isVarTypeOf(null, Object)); // returns false
console.log(isVarTypeOf(undefined, Object)); // returns false
console.log(isVarTypeOf(false, Boolean)); // returns true
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:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return _var == _type; //null and undefined are considered the same
// or you can use === if you want to differentiate them
}
}
var a = undefined, b = null;
console.log(isVarTypeOf(a, undefined)) // returns true
console.log(isVarTypeOf(b, undefined)) // returns true
console.log(isVarTypeOf(a, null)) // returns true
actualización del comentario de inanc: desafío aceptado: D
si quieres perder objetos de comparación puedes intentarlo de esta manera:
function isVarTypeOf(_var, _type, looseCompare){
if (!looseCompare){
try {
return _var.constructor === _type;
} catch(ex){
return _var == _type;
}
} else {
try{
switch(_var.constructor){
case Number:
case Function:
case Boolean:
case Symbol:
case Date:
case String:
case RegExp:
// add all standard objects you want to differentiate here
return _var.constructor === _type;
case Error:
case EvalError:
case RangeError:
case ReferenceError:
case SyntaxError:
case TypeError:
case URIError:
// all errors are considered the same when compared to generic Error
return (_type === Error ? Error : _var.constructor) === _type;
case Array:
case Int8Array:
case Uint8Array:
case Uint8ClampedArray:
case Int16Array:
case Uint16Array:
case Int32Array:
case Uint32Array:
case Float32Array:
case Float64Array:
// all types of array are considered the same when compared to generic Array
return (_type === Array ? Array : _var.constructor) === _type;
case Object:
default:
// the remaining are considered as custom class/object, so treat it as object when compared to generic Object
return (_type === Object ? Object : _var.constructor) === _type;
}
} catch(ex){
return _var == _type; //null and undefined are considered the same
// or you can use === if you want to differentiate them
}
}
}
de esa manera, puedes hacer como el comentario de inanc:
isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true
o
Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object); // returns false
isVarTypeOf(new Foo(), Object, true); // returns true
isVarTypeOf(new Bar(), Foo, true); // returns false
isVarTypeOf(new Bar(), Bar, true); // returns true
isVarTypeOf(new Bar(), Bar); // returns true
instanceof
para buscar objetos. Aún así, esto no es una ciencia exacta.
new Foo()
devuelve un Foo
objeto, igual que new String()
devuelve un String
objeto, o new Date()
devuelve un Date
objeto, se pueden hacer Foo = function(){}; isVarTypeOf(new Foo(), Foo);
también
null
es un objeto).