Почему JSON.stringify() принимает объекты Date?

По крайней мере, в Firefox вы можете форматировать объект Date:

>>> JSON.stringify({'now': new Date()})
'{"now":"2012-04-23T18:44:05.600Z"}'

Это работает, потому что (в Firefox) Date содержит метод toJSON, который используется его сериализатором JSON. Однако это не является частью стандарта JSON, поэтому я удивляюсь, почему этот метод существует или, скорее, почему встроенный JSON-сериализатор проверяет такой метод. Поскольку он не стандартизован, вы не можете безопасно его использовать без предварительного тестирования, если встроенный сериализатор его понимает и в противном случае использует пользовательский (например, json2.js)

Ответ 1

Это работает, потому что это указано в не столь ясном вопросе в спецификации. Для начала вам нужно вставить в раздел 15.12.3 в описании абстрактной операции Str, который используется для преобразования значений в строковое представление. По сути, если вход является объектом, спецификация говорит, чтобы проверить наличие вызываемого значения с именем toJSON. Подумайте об этом как о интерфейсе на Java или С#.

interface IAmJSON 
{
    string toJSON(string key);
}

Это точный текст из спецификации.

2.  If Type(value) is Object, then 
    a.  Let toJSON be the result of calling the [[Get]] internal method of  value with argument "toJSON". 
    b.  If IsCallable(toJSON) is true 
        i.  Let value be the result of calling the [[Call]] internal method of  toJSON passing value as the this value and with an argument list consisting of key. 

Наконец, объект даты имеет toJSON, определенный в разделе 15.9.5.44.