Почему "foo".toString() - это не то же самое, что toString.call( "foo" )?

Вот вопрос в JavaScript ниже:

// Tested via Google Chrome console.
var toString = Object.prototype.toString;

"foo".toString(); // "foo"
toString.call("foo"); // [object String]

[].toString(); // ""
toString.call([]); // [object Array]

{}.toString(); // syntax error
toString.call({}); // [object Object]

Почему результат toString отличается от toString.call()?

ОБНОВЛЕНО

String.prototype.toString.call("foo"); // "foo"
Object.prototype.toString.call("foo"); // [object String]

Является ли String.prototype.toString не цепочкой прототипов, как показано ниже?

toString в String [не найден] → toString в String.prototype [не найден]

                           --> toString in Object.prototype[found]

Ответ 1

String.prototype.toString отменяет Object.prototype.toString. Они не являются одной и той же функцией.

Из спецификация String.prototype.toString:

Возвращает это значение String. (Обратите внимание, что для объекта String метод toString возвращает то же самое, что метод valueOf.)

И Object.prototype.toString:

При вызове метода toString выполняются следующие шаги:

  • Пусть O является результатом вызова ToObject, передающего значение this в качестве аргумента.
  • Пусть класс является значением внутреннего свойства [[Class]] для O.
  • Возвращает значение String, которое является результатом объединения трех строк: [object ", class и ].

Массивы ведут себя аналогично, они также переопределяют toString():

> [1,2].toString()
  "1,2"

Ответ 2

>>> String.prototype.toString.call("foo")
"foo"

Объект - это не то же самое, что String.

Ответ 3

Глобальная функция toString отличается от функции object.toString(). Согласно этот источник, глобальная функция toString не очень хорошо определена и, следовательно, плохо реализована в разных браузерах. По сути, он обеспечивает функциональность, аналогичную оператору typeof.