Вопрос проверяет понимание алгоритма приведения объекта к примитиву и того, какие методы и в каком порядке использует JavaScript.
При приведении объекта к примитиву JavaScript сначала пытается вызвать valueOf, а если он не возвращает примитив, вызывает toString. Этот порядок применяется по умолчанию для числового контекста. Если результат всё ещё не примитив, выбрасывается ошибка. Поведение строго описано в спецификации.
Когда объект участвует в операциях сравнения, сложения или преобразования типов, JavaScript запускает специальный алгоритм.
Определение: ToPrimitive — алгоритм преобразования объекта в примитивное значение перед выполнением операций.
По умолчанию (числовой контекст):
Вызывается obj.valueOf()
Если результат — примитив, он используется
Иначе вызывается obj.toString()
Если результат — примитив, он используется
Иначе выбрасывается TypeError
const obj = {
valueOf() {
return {};
},
toString() {
return '10';
}
};
Number(obj); // 10
valueOf вернул объект, поэтому JavaScript перешёл к toString.
Для строкового контекста порядок может меняться:
String(obj);
В этом случае JavaScript предпочтёт toString.
Если у объекта есть метод:
obj[Symbol.toPrimitive]
он вызывается раньше valueOf и toString и полностью управляет приведением.
Вывод: по умолчанию JavaScript сначала вызывает valueOf, затем toString, но порядок может зависеть от контекста и быть переопределён через Symbol.toPrimitive.