Reputation: 5656
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
Reputation: 665465
If we leave out
.call
and just invoke it as inObject.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
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