¿Mejor manera de obtener el tipo de una variable de Javascript?
¿Hay una mejor manera de obtener el tipo de una variable en JS que typeof? Funciona bien cuando haces:
> typeof 1
"number"
> typeof "hello"
"string"
Pero es inútil cuando intentas:
> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"
Conozco instanceof, pero esto requiere que conozcas el tipo de antemano.
> [1,2] instanceof Array
true
> r instanceof RegExp
true
¿Hay una mejor manera?
Respuesta #1
Angus Croll escribió recientemente un interesante artículo en el blog sobre esto -
http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
Él repasa los pros y los contras de los distintos métodos y luego define un nuevo método 'toType' -
var toType = function(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
Respuesta #2
Puedes intentar usar constructor.name.
[].constructor.name
new RegExp().constructor.name
Como con todo en JavaScript, alguien eventualmente señalará invariablemente que esto es de alguna manera maligno, así que aquí hay un enlace a una respuesta que lo cubre bastante bien.
Una alternativa es usar Object.prototype.toString.call
Object.prototype.toString.call([])
Object.prototype.toString.call(/./)
Respuesta #3
Puede que encuentre útil la siguiente función:
function typeOf(obj) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
O en ES7 (comenta si hay más mejoras)
const { toString } = Object.prototype;
function typeOf(obj) {
const stringified = obj::toString();
const type = stringified.split(' ')[1].slice(0, -1);
return type.toLowerCase();
}
Resultados :
typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
typeOf(async function() {}) //asyncfunction
Gracias @johnrees por notificarme sobre: error, promesa, función generadora
Respuesta #4
Una función de captura de tipos razonablemente buena es la que usa YUI3:
var TYPES = {
'undefined' : 'undefined',
'number' : 'number',
'boolean' : 'boolean',
'string' : 'string',
'[object Function]': 'function',
'[object RegExp]' : 'regexp',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object Error]' : 'error'
},
TOSTRING = Object.prototype.toString;
function type(o) {
return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};
Esto captura muchas de las primitivas proporcionadas por JavaScript, pero siempre puedes añadir más modificando el objeto TYPES. Ten en cuenta que typeof HTMLElementCollection en Safari reportará function, pero type(HTMLElementCollection) devolverá object
Respuesta #5
También podemos cambiar un pequeño ejemplo de ipr101
Object.prototype.toType = function() {
return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
y llamar como
"aaa".toType(); // 'string'
Respuesta #6
función de una línea:
function type(obj) {
return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}
esto da el mismo resultado que jQuery.type()
