0

As we know, we can use the Object.prototype.toString.call(arg) if we need to detect object class.

But In my test, Object.prototype.toString.call(arg) === toString.

So, why don't we use toString.call(arg) to replace Object.prototype.toString.call(arg) which is a long type.

In the Polyfill of Array.isArray, It also use Object.prototype.toString.call(arg).

different between Object.toString and Object.prototype.toString

adiga
  • 34,372
  • 9
  • 61
  • 83
Eriice
  • 147
  • 1
  • 7
  • 3
    These are totally different methods. `instance.toString` gives a string presentation of the instance of an object, and is often overridden. And as you've noticed, calling `Object.prototype.toString` gives a "Class" of the object. For example, consider the return values of `[].toString()` and `Object.prototype.toString.call([]);` ... – Teemu Jul 12 '19 at 09:39

1 Answers1

4

It's not necessary, it just makes the code's intent more clear. When you use the toString standalone function, usually that'll refer to window.toString - window is an object, and objects inherit from Object.prototype, so window.toString === Object.prototype.toString. But relying on this sort of thing implicitly can be confusing and can produce bugs.

There's also no guarantee that there's not some other function you've defined called toString, eg:

(() => {
  const toString = () => 'here is a string';
  
  // many lines of code here
  class Foo {}
  const f = new Foo();
  // Does not result in "[object Object]":
  console.log(toString.call(f));
})();

Explicitly using Object.prototype.toString instead makes the code more understandable and predictable at a glance.

(You're still free to use toString alone instead if you want, it probably won't break anything, but it's probably not a great idea in general.)

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 1
    Why do you use an IIFE here? – Kobe Jul 12 '19 at 09:43
  • @Kobe To avoid polluting the global namespace. – Daan Jul 12 '19 at 09:45
  • 1
    Not that important, it just distinguishes the locally scoped `toString` from the `toString` visible on the top level, though even if it was on the top level, It doesn't overwrite `window.toString` if it's declared with `const`. It doesn't really matter, just slightly reduces the possibility of confusion from looking at the snippet – CertainPerformance Jul 12 '19 at 09:45
  • 1
    And `window.toString` might not necessarily be `Object.prototype.toString` (or does the Web Spec say that?) ... – Jonas Wilms Jul 12 '19 at 09:48
  • @JonasWilms Yeah, could be, that's why I said *usually*. `window.toString` is writable, it's not even a property of `window`, it's just inheriting from `Object.prototype` – CertainPerformance Jul 12 '19 at 09:50