Since when does null.toString () return [object Null]?
I'm curious because I thought that
Object.prototype.toString.call(null)
return [object Object]
, but now I've tested this in Chrome and FF and both were returning [object Null]
. Now the question is, can I assume that Object.prototype.toString will always tell me a good type?
So far I have checked every type with this method, but not for null values, I have checked for null values against
obj === null;
Thank!
Note for clarification: This "problem" is not a serious case, as atm I am using
function isNull(obj) {
return obj === null;
}
function isUndefined(obj) {
return typeof obj === 'undefined';
}
which works fine, but if Object.prototype.toString.call()
it works enough in older browsers, I can remove those two features and extend my solution with null
and undefined
, for example:
var types = ['Object', 'Number', 'String', 'Array', 'Function',
'Date', 'RegExp', 'Boolean', 'Error', 'Null', 'Undefined'].reduce(function(prev, type) {
prev['[object ' + type + ']'] = type.toLowerCase();
return prev;
}, {});
function isType(type) {
return function(obj) {
return getType(obj) === type;
};
}
function getType(obj) {
return types[Object.prototype.toString.call(obj)];
}
var isNull = isType('null');
document.querySelector('#console').textContent = isNull(null);
<div id='console'></div>
This is defined in EcmaScript 5.1 Section 15.2.4.2 -Object.prototype.toString()
:
When the method is called
toString
, the following steps are performed:
- If the value
this
is equalundefined
, return"[object Undefined]"
.- If the value
this
is equalnull
, return"[object Null]"
.- Let
O
be the result of a callToObject
passing a valuethis
as an argument.- Let be the
class
value of an internal property[[Class]]
O
.- Returns a String value that is the result of concatenating three strings
"[object "
,class
and"]"
.
EcmaScript 5 has defined it differently:
When the method is called
toString
, the following steps are performed:
- Let
O
be the result of a callToObject
passing a valuethis
as an argument.- Let be the
class
value of an internal property[[Class]]
O
.- Returns a String value that is the result of concatenating three strings
"[object "
,class
and"]"
.
Oriol's review is correct, but I wanted to add that there is a difference between calling toString
directly, like a number or string, and using Object.prototype.toString
.
The function Object.prototype.toString
is generic, so if we do
var x = "hello, world";
alert(Object.prototype.toString.call(x));
we will see "[Object String]".
However, if we call toString directly, instead, for example:
alert(x.toString());
we'll see "hello world". The reason for this is that the toString
second example is indeed String.prototype.toString
different from the generic method Object.prototype.toString
. The same difference occurs as the number 6:
var y = 6;
alert(Object.prototype.toString.call(y)); // "[Object Number]"
alert(y.toString()); // "6"
alert(Number.prototype.toString.call(y)); // also "6"
In this case, the primitive value 6 is put into the instance Number
when you execute y.toString()
. When you concatenate strings, it is a method of the object toString
that is called and not Object.prototype.toString
, so it alert("I am " + y + " years old")
produces "I am 6 years old" and not "I [object number] years old".
Since it null
does not have a prototype null
or something, execution null.toString()
will fail.