A while ago, I made an modified version of Juriy Zaytsev’s __getClass method from his `instanceof` considered harmful blog post. My modified version uses the name of the constructor (if not already set) property of an object to get the “class” of the object. If the constructor property has been set directly on an object, it falls back to the Object.prototype.toString.call method. An optional boolean second argument can be specified though to make getClass always or never return the constructor’s name. If it is true and the constructor property has been overwritten, it deletes it to reset it to the real constructor property and returns that. If it is false, it acts just like Juriy’s __getClass method. My version requires a method for getting function names, and as I have not found any good methods made for this already that only worked on functions and IE’s “function objects”, I made my own method called getFunctionName. This method will return a value if it is passed a function or an object who’s toString method returns something that looks like a function (in order to support ie).
getClass (I named mine getClass instead of __getClass)
function getClass(obj, forceConstructor) { if ( typeof obj == "undefined" ) return "undefined"; if ( obj === null ) return "null"; if ( forceConstructor == true && obj.hasOwnProperty("constructor") ) delete obj.constructor; // reset constructor if ( forceConstructor != false && !obj.hasOwnProperty("constructor") ) return getFunctionName(obj.constructor); return Object.prototype.toString.call(obj) .match(/^\[object\s(.*)\]$/)[1]; }
getFunctionName
function getFunctionName(func) { if ( typeof func == "function" || typeof func == "object" ) var fName = (""+func).match( /^function\s*(?:\s+([\w\$]*))?\s*\(/ ); if ( fName !== null ) return fName[1]; }
Examples for using getClass:
function Foo() {} var bar = new Foo getClass(bar) == "Foo" getClass(bar, false) == "Object" // ignore any constructor bar.constructor = "trying to hide the constructor" getClass(bar) == "Object" // doesn't trust constructor property so it uses fallback getClass(bar, true) == "Foo" // ONLY return the constructor's name (and therefor resets the constructor property if modified) getClass(window) == "Window" getClass(undefined) == "undefined" getClass([]) == "Array" getClass(null) == "null" getClass(true) == "Boolean" getClass(new Date) == "Date" getClass("foo") == "String" getClass(5e-324) == "Number"