简体   繁体   中英

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?

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM