javascript - texto - title html w3schools
¿Mejor manera de obtener el tipo de una variable de Javascript? (9)
¿Hay una mejor manera de obtener el tipo de variable en JS que typeof
? Funciona bien cuando haces:
> typeof 1
"number"
> typeof "hello"
"string"
Pero es inútil cuando lo intentas:
> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"
Sé de instanceof
, pero esto requiere que sepas el tipo de antemano.
> [1,2] instanceof Array
true
> r instanceof RegExp
true
¿Hay alguna manera mejor?
Angus Croll escribió recientemente una interesante publicación de blog sobre esto:
http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
Repasa los pros y los contras de los diversos 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()
}
Puede aplicar Object.prototype.toString
a cualquier objeto:
var toString = Object.prototype.toString;
console.log(toString.call([]));
//-> [object Array]
console.log(toString.call(/reg/g));
//-> [object RegExp]
console.log(toString.call({}));
//-> [object Object]
Esto funciona bien en todos los navegadores, con la excepción de IE: al invocar esto en una variable obtenida de otra ventana, solo escupirá [object Object]
.
Puede encontrar útil la siguiente función:
function typeOf(obj) {
return {}.toString.call(obj).split('' '')[1].slice(0, -1).toLowerCase();
}
O en ES7 (comentar si hay nuevas mejoras)
function typeOf(obj) {
const { toString } = Object.prototype;
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
Gracias a @johnrees por notificarme de: error, promesa, función de generador
Puedes intentar usar constructor.name
.
[].constructor.name
new RegExp().constructor.name
Como con todo JavaScript, alguien invariablemente señalará que esto es de alguna manera malo, así que aquí hay un enlace a una respuesta que cubre esto bastante bien.
Una alternativa es usar Object.prototype.toString.call
Object.prototype.toString.call([])
Object.prototype.toString.call(/./)
También podemos cambiar un pequeño ejemplo desde ipr101.
Object.prototype.toType = function() {
return ({}).toString.call(this).match(//s([a-zA-Z]+)/)[1].toLowerCase()
}
y llamar como
"aaa".toType(); // ''string''
Una función de captura de tipo 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 puede agregar más modificando el objeto TYPES
. Tenga en cuenta que typeof HTMLElementCollection
en Safari informará la function
, pero type (HTMLElementCollection) devolverá el object
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()
Mis 2 ¢! En realidad, parte de la razón por la que estoy lanzando esto aquí, a pesar de la larga lista de respuestas, es brindar un poco más de soluciones integrales y obtener retroalimentación en el futuro sobre cómo expandirlas para incluir más real types
.
Con la siguiente solución, como se mencionó anteriormente, combiné un par de soluciones encontradas aquí, así como incorporé una solución para devolver un valor de jQuery en el objeto definido de jQuery si está disponible . También agrego el método al prototipo nativo de objetos. Sé que a menudo es tabú, ya que podría interferir con otras extensiones de este tipo, pero lo dejo para el user beware
. Si no le gusta esta forma de hacerlo, simplemente copie la función base en cualquier lugar que desee y reemplace todas las variables de this
con un parámetro de argumento para pasar (como los argumentos [0]).
;(function() { // Object.realType
function realType(toLower) {
var r = typeof this;
try {
if (window.hasOwnProperty(''jQuery'') && this.constructor && this.constructor == jQuery) r = ''jQuery'';
else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1);
}
catch(e) { if (this[''toString'']) r = this.toString().slice(8, -1); }
return !toLower ? r : r.toLowerCase();
}
Object[''defineProperty''] && !Object.prototype.hasOwnProperty(''realType'')
? Object.defineProperty(Object.prototype, ''realType'', { value: realType }) : Object.prototype[''realType''] = realType;
})();
Entonces simplemente use con facilidad, así:
obj.realType() // would return ''Object''
obj.realType(true) // would return ''object''
Nota: Hay 1 argumento pasable. Si es bool de
true
, entonces el retorno siempre será en minúsculas .
Más ejemplos:
true.realType(); // "Boolean"
var a = 4; a.realType(); // "Number"
$(''div:first'').realType(); // "jQuery"
document.createElement(''div'').realType() // "HTMLDivElement"
Si tiene algo que agregar que pueda ser útil, como definir cuándo se creó un objeto con otra biblioteca (Moo, Proto, Yui, Dojo, etc.), no dude en comentar o editar esto y siga así exacto y preciso. O ruédese sobre el GitHub que hice para hacerlo y hágamelo saber. También encontrarás un enlace rápido a un archivo cdn min allí.
function getType(obj) {
if(obj && obj.constructor && obj.constructor.name) {
return obj.constructor.name;
}
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
En mis pruebas preliminares, esto está funcionando bastante bien. El primer caso imprimirá el nombre de cualquier objeto creado con "nuevo", y el segundo caso debería detectar todo lo demás.
Estoy usando (8, -1)
porque supongo que el resultado siempre va a comenzar con [object
y terminar con ]
pero no estoy seguro de que eso sea cierto en todos los escenarios.