objetos - metodos en javascript
Obtener el nombre del tipo de un objeto (18)
¿Hay un equivalente de JavaScript de class.getName()
de Java?
¿Hay un equivalente de JavaScript de
class.getName()
de Java?
No
Actualización ES2015 : el nombre de la class Foo {}
es Foo.name
. El nombre de la clase de thing
, sin importar el tipo de thing
, es thing.constructor.name
. Los constructores integrados en un entorno ES2015 tienen la propiedad de name
correcta; por ejemplo (2).constructor.name
es "Number"
.
Pero aquí hay varios hacks que caen de una forma u otra:
Aquí hay un hack que hará lo que necesites: ten en cuenta que modifica el prototipo del Objeto, algo que la gente no ve bien (generalmente por una buena razón)
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})/(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Ahora, todos sus objetos tendrán la función, getName()
, que devolverá el nombre del constructor como una cadena. He probado esto en FF3
e IE7
, no puedo hablar de otras implementaciones.
Si no quieres hacer eso, aquí hay una discusión sobre las diversas formas de determinar los tipos en JavaScript ...
Recientemente actualicé esto para ser un poco más exhaustivo, aunque no es eso. Correcciones de bienvenida ...
Usando la propiedad del constructor
...
Cada object
tiene un valor para su propiedad de constructor
, pero dependiendo de cómo se construyó ese object
y qué quiere hacer con ese valor, puede o no ser útil.
En términos generales, puede usar la propiedad del constructor
para probar el tipo del objeto de la siguiente manera:
var myArray = [1,2,3];
(myArray.constructor == Array); // true
Entonces, eso funciona lo suficientemente bien para la mayoría de las necesidades. Dicho esto ...
Advertencias
No funcionará en absoluto en muchos casos
Este patrón, aunque roto, es bastante común:
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects
construidos a través del new Thingy
tendrán una propiedad de constructor
que apunta a Object
, no a Thingy
. Así que caemos desde el principio; simplemente no puedes confiar en el constructor
en una base de código que no controlas.
Herencia múltiple
Un ejemplo en el que no es tan obvio es el uso de herencia múltiple:
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Las cosas ahora no funcionan como podría esperarse:
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
Por lo tanto, podría obtener resultados inesperados si el object
su prueba tiene un object
diferente configurado como su prototype
. Hay formas de evitar esto fuera del alcance de esta discusión.
Hay otros usos para la propiedad del constructor
, algunos interesantes, otros no tanto; por ahora no profundizaremos en esos usos ya que no es relevante para esta discusión.
No funcionará cross-frame y cross-window
El uso de .constructor
para la verificación de tipos se interrumpirá cuando desee verificar el tipo de objetos que provienen de diferentes objetos de la window
, por ejemplo, un iframe o una ventana emergente. Esto se debe a que hay una versión diferente de cada constructor
tipo de núcleo en cada ''ventana'', es decir,
iframe.contentWindow.Array === Array // false
Usando el operador instanceof
...
El operador instanceof
es también una forma limpia de probar el tipo de object
, pero tiene sus propios problemas potenciales, al igual que la propiedad del constructor
.
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
Pero instanceof
no funciona con valores literales (porque los literales no son Objects
)
3 instanceof Number // false
''abc'' instanceof String // false
true instanceof Boolean // false
Los literales deben estar envueltos en un Object
para que, por ejemplo, funcione, por ejemplo.
new Number(3) instanceof Number // true
El .constructor
check funciona bien para los literales porque el .
invocación de método implícitamente envuelve los literales en su respectivo tipo de objeto
3..constructor === Number // true
''abc''.constructor === String // true
true.constructor === Boolean // true
¿Por qué dos puntos para el 3? Porque Javascript interpreta el primer punto como un punto decimal;)
No funcionará cross-frame y cross-window
instanceof
tampoco funcionará en diferentes ventanas, por la misma razón que la verificación de la propiedad del constructor
.
Usando la propiedad name
de la propiedad constructor
...
No funciona en absoluto en muchos casos
Una vez más, ver más arriba; Es bastante común que el constructor
sea total y completamente incorrecto e inútil.
NO funciona en <IE9
El uso de myObjectInstance.constructor.name
le dará una cadena que contiene el nombre de la función constructor
utilizada, pero está sujeta a las advertencias sobre la propiedad del constructor
que se mencionaron anteriormente.
Para IE9 y superior, puedes usar Monkey-Patch en soporte :
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, ''name'', {
get: function() {
var funcNameRegex = /function/s+([^/s(]+)/s*/(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1] : "";
},
set: function(value) {}
});
}
Versión actualizada del artículo en cuestión. Esto se agregó 3 meses después de la publicación del artículo, esta es la versión recomendada para usar por el autor del artículo, Matthew Scharley. Este cambio se inspiró en los comentarios que señalan posibles errores en el código anterior.
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, ''name'', {
get: function() {
var funcNameRegex = /function/s([^(]{1,})/(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1].trim() : "";
},
set: function(value) {}
});
}
Utilizando Object.prototype.toString
Resulta que, como esta publicación detalla , puedes usar Object.prototype.toString
- la implementación de bajo nivel y genérica de toString
- para obtener el tipo para todos los tipos incorporados
Object.prototype.toString.call(''abc'') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Uno podría escribir una función de ayuda corta como
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
para eliminar el cruft y obtener sólo el nombre de tipo
type(''abc'') // String
Sin embargo, devolverá Object
para todos los tipos definidos por el usuario.
Advertencias para todos ...
Todo esto está sujeto a un problema potencial, y esa es la cuestión de cómo se construyó el objeto en cuestión. Aquí hay varias formas de construir objetos y los valores que devolverán los diferentes métodos de verificación de tipos:
// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == "Foo"); // true
// let''s add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // false
(obj.constructor.name == "Foo"); // false
// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object); // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == ""); // true
// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == ""); // true
// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object); // true
(obj.constructor == Object); // true
(obj.constructor.name == "Object"); // true
Si bien no todas las permutaciones están presentes en este conjunto de ejemplos, es de esperar que haya suficientes para proporcionarle una idea de cómo las cosas sucias pueden ponerse en función de sus necesidades. No asuma nada, si no entiende exactamente lo que está buscando, puede terminar con el descifrado de código en el que no espera hacerlo debido a la falta de asimilación de las sutilezas.
NOTA:
La discusión del operador de typeof
puede parecer una omisión evidente, pero en realidad no es útil para ayudar a identificar si un object
es un tipo dado, ya que es muy simplista. Comprender dónde es útil typeof
es importante, pero actualmente no creo que sea terriblemente relevante para esta discusión. Sin embargo, mi mente está abierta al cambio. :)
Actualizar
Para ser precisos, creo que OP solicitó una función que recupera el nombre del constructor para un objeto en particular. En términos de Javascript, el object
no tiene un tipo, pero es un tipo de y en sí mismo . Sin embargo, diferentes objetos pueden tener diferentes constructores .
Object.prototype.getConstructorName = function () {
var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
var cname = str.match(/function/s(/w*)/)[1];
var aliases = ["", "anonymous", "Anonymous"];
return aliases.indexOf(cname) > -1 ? "Function" : cname;
}
new Array().getConstructorName(); // returns "Array"
(function () {})().getConstructorName(); // returns "Function"
Nota: el siguiente ejemplo está en desuso.
Una publicación de blog vinculada por Christian Sciberras contiene un buen ejemplo de cómo hacerlo. A saber, ampliando el prototipo de Objeto:
if (!Object.prototype.getClassName) {
Object.prototype.getClassName = function () {
return Object.prototype.toString.call(this).match(/^/[object/s(.*)/]$/)[1];
}
}
var test = [1,2,3,4,5];
alert(test.getClassName()); // returns Array
Aquí hay una implementación basada en la respuesta aceptada :
/**
* Returns the name of an object''s type.
*
* If the input is undefined, returns "Undefined".
* If the input is null, returns "Null".
* If the input is a boolean, returns "Boolean".
* If the input is a number, returns "Number".
* If the input is a string, returns "String".
* If the input is a named function or a class constructor, returns "Function".
* If the input is an anonymous function, returns "AnonymousFunction".
* If the input is an arrow function, returns "ArrowFunction".
* If the input is a class instance, returns "Object".
*
* @param {Object} object an object
* @return {String} the name of the object''s class
* @see <a href="https://.com/a/332429/14731">https://.com/a/332429/14731</a>
* @see getFunctionName
* @see getObjectClass
*/
function getTypeName(object)
{
const objectToString = Object.prototype.toString.call(object).slice(8, -1);
if (objectToString === "Function")
{
const instanceToString = object.toString();
if (instanceToString.indexOf(" => ") != -1)
return "ArrowFunction";
const getFunctionName = /^function ([^(]+)/(/;
const match = instanceToString.match(getFunctionName);
if (match === null)
return "AnonymousFunction";
return "Function";
}
// Built-in types (e.g. String) or class instances
return objectToString;
};
/**
* Returns the name of a function.
*
* If the input is an anonymous function, returns "".
* If the input is an arrow function, returns "=>".
*
* @param {Function} fn a function
* @return {String} the name of the function
* @throws {TypeError} if {@code fn} is not a function
* @see getTypeName
*/
function getFunctionName(fn)
{
try
{
const instanceToString = fn.toString();
if (instanceToString.indexOf(" => ") != -1)
return "=>";
const getFunctionName = /^function ([^(]+)/(/;
const match = instanceToString.match(getFunctionName);
if (match === null)
{
const objectToString = Object.prototype.toString.call(fn).slice(8, -1);
if (objectToString === "Function")
return "";
throw TypeError("object must be a Function./n" +
"Actual: " + getTypeName(fn));
}
return match[1];
}
catch (e)
{
throw TypeError("object must be a Function./n" +
"Actual: " + getTypeName(fn));
}
};
/**
* @param {Object} object an object
* @return {String} the name of the object''s class
* @throws {TypeError} if {@code object} is not an Object
* @see getTypeName
*/
function getObjectClass(object)
{
const getFunctionName = /^function ([^(]+)/(/;
const result = object.constructor.toString().match(getFunctionName)[1];
if (result === "Function")
{
throw TypeError("object must be an Object./n" +
"Actual: " + getTypeName(object));
}
return result;
};
function UserFunction()
{
}
function UserClass()
{
}
let anonymousFunction = function()
{
};
let arrowFunction = i => i + 1;
console.log("getTypeName(undefined): " + getTypeName(undefined));
console.log("getTypeName(null): " + getTypeName(null));
console.log("getTypeName(true): " + getTypeName(true));
console.log("getTypeName(5): " + getTypeName(5));
console.log("getTypeName(/"text/"): " + getTypeName("text"));
console.log("getTypeName(userFunction): " + getTypeName(UserFunction));
console.log("getFunctionName(userFunction): " + getFunctionName(UserFunction));
console.log("getTypeName(anonymousFunction): " + getTypeName(anonymousFunction));
console.log("getFunctionName(anonymousFunction): " + getFunctionName(anonymousFunction));
console.log("getTypeName(arrowFunction): " + getTypeName(arrowFunction));
console.log("getFunctionName(arrowFunction): " + getFunctionName(arrowFunction));
//console.log("getFunctionName(userClass): " + getFunctionName(new UserClass()));
console.log("getTypeName(userClass): " + getTypeName(new UserClass()));
console.log("getObjectClass(userClass): " + getObjectClass(new UserClass()));
//console.log("getObjectClass(userFunction): " + getObjectClass(UserFunction));
//console.log("getObjectClass(userFunction): " + getObjectClass(anonymousFunction));
//console.log("getObjectClass(arrowFunction): " + getObjectClass(arrowFunction));
console.log("getTypeName(nativeObject): " + getTypeName(navigator.mediaDevices.getUserMedia));
console.log("getFunctionName(nativeObject): " + getFunctionName(navigator.mediaDevices.getUserMedia));
Solo usamos la propiedad del constructor cuando no tenemos otra opción.
Aquí hay una solución que he encontrado que resuelve las deficiencias de instanceof. Puede verificar los tipos de un objeto desde ventanas cruzadas y marcos cruzados y no tiene problemas con los tipos primitivos.
function getType(o) {
return Object.prototype.toString.call(o).match(/^/[object/s(.*)/]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object''s window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we''ll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object''s window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
isInstance requiere dos parámetros: un objeto y un tipo. El verdadero truco de cómo funciona es que comprueba si el objeto es de la misma ventana y, si no, obtiene la ventana del objeto.
Ejemplos:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
El argumento de tipo también puede ser una función de devolución de llamada que devuelve un constructor. La función de devolución de llamada recibirá un parámetro que es la ventana del objeto proporcionado.
Ejemplos:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
Una cosa a tener en cuenta es que IE <9 no proporciona el constructor en todos los objetos, por lo que la prueba anterior para NodeList devolvería falso y también una isInstance (alerta, "Función") devolvería falso.
Debe usar somevar.constructor.name
como a:
const getVariableType = a => a.constructor.name.toLowerCase();
const d = new Date();
const res1 = getVariableType(d); // ''date''
const num = 5;
const res2 = getVariableType(num); // ''number''
const fn = () => {};
const res3 = getVariableType(fn); // ''function''
console.log(res1); // ''date''
console.log(res2); // ''number''
console.log(res3); // ''function''
Digamos que tienes var obj;
Si solo quieres el nombre del tipo de obj, como "Objeto", "Array" o "Cadena", puedes usar esto:
Object.prototype.toString.call(obj).split('' '')[1].replace('']'', '''');
En realidad estaba buscando algo similar y me encontré con esta pregunta. Así es como obtengo los tipos: jsfiddle
var TypeOf = function ( thing ) {
var typeOfThing = typeof thing;
if ( ''object'' === typeOfThing ) {
typeOfThing = Object.prototype.toString.call( thing );
if ( ''[object Object]'' === typeOfThing ) {
if ( thing.constructor.name ) {
return thing.constructor.name;
}
else if ( ''['' === thing.constructor.toString().charAt(0) ) {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
else {
typeOfThing = thing.constructor.toString().match( /function/s*(/w+)/ );
if ( typeOfThing ) {
return typeOfThing[1];
}
else {
return ''Function'';
}
}
}
else {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
}
return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}
La función kind () de Agave.JS devolverá:
- El prototipo más cercano en el árbol de herencia.
- para tipos siempre primitivos como ''nulo'' e ''indefinido'', el nombre primitivo.
Funciona en todos los objetos y primitivas de JS, independientemente de cómo se crearon , y no tiene sorpresas. Ejemplos:
Números
kind(37) === ''Number''
kind(3.14) === ''Number''
kind(Math.LN2) === ''Number''
kind(Infinity) === ''Number''
kind(Number(1)) === ''Number''
kind(new Number(1)) === ''Number''
Yaya
kind(NaN) === ''NaN''
Instrumentos de cuerda
kind('''') === ''String''
kind(''bla'') === ''String''
kind(String("abc")) === ''String''
kind(new String("abc")) === ''String''
Booleanos
kind(true) === ''Boolean''
kind(false) === ''Boolean''
kind(new Boolean(true)) === ''Boolean''
Arrays
kind([1, 2, 4]) === ''Array''
kind(new Array(1, 2, 3)) === ''Array''
Objetos
kind({a:1}) === ''Object''
kind(new Object()) === ''Object''
fechas
kind(new Date()) === ''Date''
Funciones
kind(function(){}) === ''Function''
kind(new Function("console.log(arguments)")) === ''Function''
kind(Math.sin) === ''Function''
indefinido
kind(undefined) === ''undefined''
nulo
kind(null) === ''null''
La respuesta de Jason Bunting me dio una pista suficiente para encontrar lo que necesitaba:
<<Object instance>>.constructor.name
Así, por ejemplo, en el siguiente fragmento de código:
function MyObject() {}
var myInstance = new MyObject();
myInstance.constructor.name
devolvería "MyObject"
.
Lo más cercano que puede obtener es typeof
, pero solo devuelve "objeto" para cualquier tipo de tipo personalizado. Para aquellos, ver Jason Bunting .
Edit, Jason eliminó su publicación por algún motivo, así que solo usa la propiedad de constructor
de Object.
Lodash tiene muchos isMethods, así que si estás usando Lodash, tal vez una combinación como esta pueda ser útil:
// Mixin for identifying a Javascript Object
_.mixin({
''identify'' : function(object) {
var output;
var isMethods = [''isArguments'', ''isArray'', ''isArguments'', ''isBoolean'', ''isDate'', ''isArguments'',
''isElement'', ''isError'', ''isFunction'', ''isNaN'', ''isNull'', ''isNumber'',
''isPlainObject'', ''isRegExp'', ''isString'', ''isTypedArray'', ''isUndefined'', ''isEmpty'', ''isObject'']
this.each(isMethods, function (method) {
if (this[method](object)) {
output = method;
return false;
}
}.bind(this));
return output;
}
});
Agrega un método para "lodash" llamado "identificar" que funciona de la siguiente manera:
console.log(_.identify(''hello friend'')); // isString
Ok, amigos, poco a poco he estado construyendo un método de captura para esto durante algunos años, jajaja! El truco es:
- Disponer de un mecanismo para crear clases.
- Tener un mecanismo para verificar todas las clases creadas por el usuario, primitivos y valores creados / generados por constructores nativos.
- Tenga un mecanismo para extender las clases creadas por el usuario a nuevas clases, de modo que la funcionalidad anterior penetre a través de su código / aplicación / biblioteca / etc.
Para ver un ejemplo (o ver cómo resolví el problema), consulte el siguiente código en github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js y busque:
classOf =
, classOfIs =
, y o defineSubClass =
(sin los defineSubClass =
(`)).
Como puede ver, tengo implementados algunos mecanismos para obligar a classOf
a que siempre me dé el nombre de tipo de clases / constructores, independientemente de si es una clase primitiva, definida por el usuario, un valor creado mediante un constructor nativo, Null, NaN, etc. Para cada valor único de javascript obtendré su nombre de tipo único de la función classOf
. Además, puedo pasar los constructores reales a sjl.classOfIs
para verificar el tipo de un valor además de poder pasar su nombre de tipo también. Así por ejemplo:
`` `// ¡Por favor, perdona los espacios de nombres largos! No tenía idea del impacto hasta después de usarlos por un tiempo (chupan jaja)
var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
constructor: function SomeCustomClass () {},
// ...
}),
HelloIterator = sjl.ns.stdlib.Iterator.extend(
function HelloIterator () {},
{ /* ... methods here ... */ },
{ /* ... static props/methods here ... */ }
),
helloIt = new HelloIterator();
sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`
var someString = ''helloworld'';
sjl.classOfIs(someString, String) === true; // `true`
sjl.classOfIs(99, Number) === true; // true
sjl.classOf(NaN) === ''NaN''; // true
sjl.classOf(new Map()) === ''Map'';
sjl.classOf(new Set()) === ''Set'';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`
// etc..
// Also optionally the type you want to check against could be the type''s name
sjl.classOfIs([''a'', ''b'', ''c''], ''Array'') === true; // `true`!
sjl.classOfIs(helloIt, ''HelloIterator'') === true; // `true`!
`` `
Si está interesado en leer más sobre cómo uso la configuración mencionada anteriormente, consulte el repositorio: https://github.com/elycruz/sjljs
También libros con contenido sobre el tema: - "Patrones de JavaScript" por Stoyan Stefanov. - "Javascript - La Guía Definitiva". por David Flanagan. - y muchos otros .. (search le` web).
También puede probar rápidamente las características de las que estoy hablando aquí: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (también la ruta 0.5.18 en la url tiene las fuentes de github en allí menos los node_modules y tal).
¡Feliz codificación!
Puede usar el operador "instanceof" para determinar si un objeto es una instancia de cierta clase o no. Si no conoce el nombre del tipo de un objeto, puede usar su propiedad de constructor. La propiedad constructora de los objetos, es una referencia a la función que se utiliza para inicializarlos. Ejemplo:
function Circle (x,y,radius) {
this._x = x;
this._y = y;
this._radius = raduius;
}
var c1 = new Circle(10,20,5);
Ahora c1.constructor es una referencia a la función Circle()
. También puede utilizar el operador typeof
, pero el operador typeof
muestra información limitada. Una solución es usar el método toString()
del objeto global Objeto. Por ejemplo, si tiene un objeto, diga myObject, puede usar el método toString()
del objeto global para determinar el tipo de la clase de myObject. Utilizar esta:
Object.prototype.toString.apply(myObject);
Puede usar el operador instanceof
para ver si un objeto es una instancia de otro, pero como no hay clases, no puede obtener un nombre de clase.
Si alguien estaba buscando una solución que funcione con jQuery, aquí está el código wiki ajustado (el original rompe jQuery).
Object.defineProperty(Object.prototype, "getClassName", {
value: function() {
var funcNameRegex = /function (.{1,})/(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}
});
Un pequeño truco que utilizo:
function Square(){
this.className = "Square";
this.corners = 4;
}
var MySquare = new Square();
console.log(MySquare.className); // "Square"
Use constructor.name
cuando pueda y regex funcione cuando no pueda.
Function.prototype.getName = function(){
if (typeof this.name != ''undefined'')
return this.name;
else
return /function (.+)/(/.exec(this.toString())[1];
};
Utilizando Object.prototype.toString
Resulta que, como esta publicación detalla, puedes usar Object.prototype.toString - la implementación de bajo nivel y genérica de toString - para obtener el tipo para todos los tipos incorporados
Object.prototype.toString.call(''abc'') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
Uno podría escribir una función de ayuda corta como
function type(obj){
return Object.prototype.toString.call(obj]).match(//s/w+/)[0].trim()
}
return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function