Вопрос проверяет понимание механизма преобразования объектов в строки в JavaScript, что важно для отладки, логирования и корректного отображения данных.
В JavaScript преобразование объекта к строке происходит в контексте явного (String(obj)) или неявного приведения типа, например, при конкатенации с строкой (obj + '') или передаче в alert(). Механизм следует общим правилам абстрактной операции ToPrimitive с хинтом 'string'.
Когда движку нужно получить примитивное значение из объекта, он выполняет следующие шаги:
@@toPrimitive (символьный метод [Symbol.toPrimitive]), он вызывается с хинтом 'string' и его результат используется.toString(). Если он возвращает примитивное значение (не объект), преобразование завершено.toString() отсутствует или возвращает объект, вызывается метод valueOf(). Если он возвращает примитив, он используется.toString(), и valueOf() отсутствуют или возвращают объекты, генерируется ошибка TypeError.Рассмотрим кастомное поведение:
const obj = {
name: 'Test',
// Приоритет 1: Symbol.toPrimitive
[Symbol.toPrimitive](hint) {
if (hint === 'string') {
return `Object: ${this.name}`;
}
return 42; // для числового контекста
}
};
console.log(String(obj)); // 'Object: Test'
console.log(obj + ''); // 'Object: Test' (неявное)
Пример с переопределением toString и valueOf:
const user = {
age: 30,
toString() {
return `User age: ${this.age}`;
},
valueOf() {
return this.age;
}
};
// В строковом контексте используется toString:
alert(user); // 'User age: 30'
// В числовом контексте (например, сравнение) используется valueOf:
console.log(user > 20); // true (30 > 20)
Стандартный метод Object.prototype.toString() можно использовать для определения типа объекта:
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
Понимание этого механизма критично для:
toString может возвращать JSON или форматированную строку.obj + 'text'.Вывод: Переопределяйте toString() (или [Symbol.toPrimitive]) в своих объектах, когда нужно контролировать их строковое представление для логирования, вывода пользователю или интеграции со строковыми операциями.