Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

javascript

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>
like image 532
Jim-Y Avatar asked Sep 17 '14 16:09

Jim-Y


2 Answers

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.

like image 62
Chris Middleton Avatar answered Oct 26 '22 20:10

Chris Middleton


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 "]".
like image 35
Oriol Avatar answered Oct 26 '22 21:10

Oriol