Joji
Joji

Reputation: 5656

JavaScript: differences between `Object.prototype.toString.call(foo)` and `Object.prototype.toString(foo)`

I have been trying to find a better way to check data types in JavaScript. I know there are typeof and instanceof operators but they all have some pitfalls. And I found there is a method toString on Object.prototype can solve this very elegantly because it can differentiate all of the types by returning different strings based on Symbol.toStringTag

Object.prototype.toString.call(function(){})  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"

And it also works on primitive types.

However one thing I don't quite understand is that if we leave out .call from Object.prototype.toString and we just invoke it as in Object.prototype.toString() it returns [object Object] for everything.

So my question is what is it that makes .call result in correct strings for types?

Upvotes: 0

Views: 98

Answers (2)

Bergi
Bergi

Reputation: 665465

If we leave out .call and just invoke it as in Object.prototype.toString() it returns [object Object] for everything.

That is to be expected - you are calling that toString method (which ignores its argument, and depends only on the this context of the call) on the Object.prototype object.

You'll want to have a look at the call method documentation and how the this keyword works. In short:

"use strict";
function demo(...args) {
  console.log(`this: ${this}, args: ${args}`);
}
const obj = { method: demo, toString() { return "the object"} };
demo(obj, 0);
demo.call(obj, 1);
obj.method(2);

Upvotes: 0

Imran Rafiq Rather
Imran Rafiq Rather

Reputation: 8118

call() is a method available on functions as functions are first-class citizens in javascript.

It sets the context of this keyword in your function toString.call(argument1). argument1 is what the this keyword will point to.

Know more about call() function from MDN DOCS to get a clear idea about how it works.

Upvotes: 1

Related Questions