Dmitry Minkovsky
Dmitry Minkovsky

Reputation: 38203

Why is toString.call('my string') different from 'my string'.toString(), or, why is document.toString !== 'asd'.toString?

Was reading Underscore.js to see out how its is[String|Number|...] methods work, and now I am confused. Underscore does:

toString.call(obj) == ['object ' + name + ']';

Okay, so, I can do

>>> toString.call('my string')
"[object String]"

But

>>> 'my string'.toString()
"my string"

I'm pretty lost here! In the first call I've got:

>>> document.toString === toString
true

And

>>> document.toString === 'asd'.toString
false

So, I'm pretty confused. I didn't expect this behavior.

Upvotes: 2

Views: 158

Answers (1)

Ja͢ck
Ja͢ck

Reputation: 173662

That's because:

document.toString === Object.prototype.toString

It implements the most basic version of toString, one that's similar to:

'[object ' + (typeof this) + ']';

This is very different from String.toString(), which simply outputs the string itself, i.e.:

> String.prototype.toString.call('hello world')
"hello world"

Or Array.toString() which outputs a comma separated string of values.

> Array.prototype.toString.call([1,2,3])
"1,2,3"

Using .call()

To make this work, they basically apply toString() on an object by using .call():

toString.call(obj)

Inside the toString method, this now refers to obj. This would be equivalent:

Object.prototype.toString.call(obj)

Upvotes: 4

Related Questions