¿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 objectJavaScript, 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!).
typeofes un operador, por lo que no es necesario ().
typeofdevuelve 'objeto' para nulo, que no es un objeto, y instanceofno 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 !== 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 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'truenullundefined¿Qué es un objeto (es decir, no un primitivo)?
Object.prototypeObject.prototype
Function.prototype
ObjectFunctionfunction 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 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
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.getPrototypeOfque 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 truepara matrices.
var x = []; console.log(x === Object(x)); // return true
getPrototypeOfno 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]'
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 .
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
isObjectsolo 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 falseserá devuelta. La nullprueba 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 lengthatributo, 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 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.
lengthpropiedad (quise decir que los literales de objeto no tienen lengthatributo 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 nulles "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).
isObjectno funcionará en caso de Object.create(null)que la implementación interna Object.createse explica aquí, pero puede usarla isObjecten 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! 🙂
isDatepara suDateObject con el propósito de escribir código robusto, de lo contrario tendrá quebradizoisObject método .
Dateen mi comentario fue mal elegido porque sí, la respuesta sí discute Date. Pero Datees 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 constructorpropiedad 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.namedevuelve 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, undefinedy null), pero debe devolver cierto para todo lo demás (incluyendo Number, Booleany Stringobjetos). Tenga en cuenta que JS no define qué objetos "host", como windowo 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.toStringTagahora permite personalizar la salida de Object.prototype.toString.call(...), la isPlainObjectfunción anterior podría volver falseen 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 anyVares 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 no nullprimitivos. Entonces, una forma de verificar si un valor es un objeto sería asegurar que la cadena devuelta por typeofno 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 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 ===:
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 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.
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 thisvalor fuera un objeto. Se introdujo ECMAScript 3 Function.prototype.call, que permitió llamar a una función con un thisvalor 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.createy Object.getPrototypeOfrequieren 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 trydeclaración para detectar errores. Algunos ejemplos ocultos, no vale la pena comentar
Nota: intencionalmente omití algunos enfoques como Object.getPrototypeOf(value)(ES5) y Reflectmétodos (ES6) porque llaman métodos internos esenciales que pueden hacer cosas desagradables, por ejemplo, si valuees un proxy. Por razones de seguridad, mis ejemplos solo hacen referencia valuesin 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, Datey functions son todos los objetos. Aunque, nulles un poco artificial. Por lo tanto, es mejor verificar el nullprimero, para detectar que no es nulo.
Comprobación de typeof o === 'object'garantías que oes un objeto. Sin esta comprobación, no Object.prototype.toStringtendría sentido, ya que devolvería el objeto para todo, ¡incluso para undefinedy 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 oes un objeto, un objeto derivado como Array, Dateo a function.
En isDerivedObjectfunción, comprueba si oes 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 prototypepara un objectsolo 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]'
nullcheque, 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 instanceofoperador. 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.
_.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.
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
nullel 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 Functioncualquier 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?
nulllanza una excepciónUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOfo 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 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 ejemplo typeof null === 'object'). A continuación se muestra una función que determina si la variable ves un objeto repitiendo esencialmente dos verificaciones:
vis '[object Object]'. vse 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 ves 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");
}
valuees nullesto arrojará un error ...
falsepara 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 nulles, 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
trueparanew 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
instanceofpara buscar objetos. Aún así, esto no es una ciencia exacta.
new Foo()devuelve un Fooobjeto, igual que new String()devuelve un Stringobjeto, o new Date()devuelve un Dateobjeto, se pueden hacer Foo = function(){}; isVarTypeOf(new Foo(), Foo);también
nulles un objeto).