Reputation: 1522
I know that we can detect a variable's type in Javascript like this:
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call(''); // [object String]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(function () {}); // [object Function]
Object.prototype.toString.call(/test/i); // [object RegExp]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(); // [object Undefined]
But why?
How are these values ([object Array], [object String]...) returned, and what does Object.prototype.toString
do?
Upvotes: 3
Views: 1056
Reputation: 1135
If you happen to be using ECMA 6, (Like on NodeJS, or Newer browser tech) you can use the following function to get 'class name'.
// primitives
var array = [], obj = {}, str = "", date = new Date(),
num = 1, flt = 1.0, reg = new RegExp(/woohoo/g),
bool = true, myType = new MyType(), udf = undefined, nul = null;
// names of various types (primitive and not)
var names = cName(array) + ", " + cName(obj) + ", " + cName(str) + ", " +
cName(num) + ", " + cName(flt) + ", " + cName(reg) + ", " +
cName(bool) + ", " + cName(date) + ", " + cName(myType) + ", " +
cName(MyType) + ", " + cName(udf) + ", " + cName(nul);
// custom type
function MyType(){}
console.log( names );
// output:
// Array, Object, String, Number, Number, RegExp, Boolean, Date, MyType, MyType, undefined, null
// implementation
function cName(obj){
// default to non-null value.
var ret = '';
if(typeof obj === 'undefined') { ret = 'undefined'; }
else if(obj === null) { ret = String(obj); }
else if(typeof obj.constructor !== 'undefined' && obj.constructor !== null){
ret = obj.constructor.name
if(ret == 'Function') { ret = obj.name; }
}
return ret;
}
Although there really are no 'classes', this helps when being passed something like Array, vs Object, vs. Null
and you want to know which one it is.
calling typeof
on any of those will return 'object'
. Then there is the the caveat of having to deal with things like null
and undefined
.
Calling Object.prototype.toString()
is heavier than accessing constructor.name
as there is no conversion from some type to a string, and I believe the constructor
and constructor.name
are both member variables, not a getter
, which means no additional functions are called in retrieving said name.
Upvotes: 0
Reputation: 239573
Object.prototype.toString
basically returns the [[Class]]
(implementation detail) internal property of the objects. Quoting the section from ECMA Script 5.1 specification, where this is defined
- If the
this
value isundefined
, return"[object Undefined]"
.- If the
this
value isnull
, return"[object Null]"
.- Let O be the result of calling
ToObject
passing thethis
value as the argument.- Let class be the value of the
[[Class]]
internal property of O.- Return the String value that is the result of concatenating the three Strings
"[object "
,class
, and"]"
.
Also,
The value of the
[[Class]]
internal property is defined by this specification for every kind of built-in object. The value of the[[Class]]
internal property of a host object may be any String value except one of"Arguments"
,"Array"
,"Boolean"
,"Date"
,"Error"
,"Function"
,"JSON"
,"Math"
,"Number"
,"Object"
,"RegExp"
, and"String"
. The value of a[[Class]]
internal property is used internally to distinguish different kinds of objects. Note that this specification does not provide any means for a program to access that value except throughObject.prototype.toString
.
So, Object.prototype.toString
is the only function which can access the [[Class]]
property.
Upvotes: 7