Attila Kling
Attila Kling

Reputation: 1787

Since when does null.toString() return [object Null]?

I'm curious, becouse i thought that

Object.prototype.toString.call(null)

return [object Object], but now i was checking that in Chrome and FF and both returned [object Null]. Now the question is, wether i can assume that Object.prototype.toString will always tell me the good type?

Until now, i was checking every type with this method, but not for null values, i was checking null values by

obj === null;

Thanks!


Note for clarification: this 'problem' is not a serious case, since atm i'm using

function isNull(obj) {
  return obj === null;
}

function isUndefined(obj) {
  return typeof obj === 'undefined';  
}

which works just fine, but if Object.prototype.toString.call() would work sufficient in older browsers, i could drop these two functions and extend my solution with null and undefined like:

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>

Upvotes: 8

Views: 15681

Answers (2)

Oriol
Oriol

Reputation: 288580

This is defined in EcmaScript 5.1 Section 15.2.4.2 - Object.prototype.toString():

When the toString method is called, the following steps are taken:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".

EcmaScript 5 defined it differently:

When the toString method is called, the following steps are taken:

  1. Let O be the result of calling ToObject passing the this value as the argument.
  2. Let class be the value of the [[Class]] internal property of O.
  3. Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".

Upvotes: 5

Chris Middleton
Chris Middleton

Reputation: 5942

Oriol's answer is right, but I wanted to add that there is a difference between calling toString directly on, say, a number or a string, vs. using Object.prototype.toString.

The Object.prototype.toString function is general, 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, like this:

alert(x.toString());

we will see "hello, world". The reason for this is that toString in the second example is really String.prototype.toString, which is different from the generic Object.prototype.toString method. The same distinction occurs with a number like 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 being boxed into an instance of Number when you do y.toString(). When you concatenate strings, it's the object's toString method that gets called, not Object.prototype.toString, which is why alert("I am " + y + " years old") produces "I am 6 years old", not "I am [Object Number] years old".

Since null has no Null prototype or anything like that, doing null.toString() will produce an error.

Upvotes: 4

Related Questions