ValueOf: примеры (JAVASCRIPT)
valueOf: primitiveЧто такое метод valueOf в JavaScript
Метод valueOf() принадлежит объекту Object и возвращает примитивное значение указанного объекта. В JavaScript многие встроенные объекты переопределяют этот метод для возврата более подходящего значения. По умолчанию метод возвращает сам объект.
Использование метода valueOf() актуально в ситуациях, когда объект участвует в операциях, требующих примитивного значения. Например, при математических операциях или сравнении. JavaScript автоматически вызывает этот метод, когда объект встречается в контексте, где ожидается примитивное значение.
Параметры метода
Метод valueOf() не принимает никаких параметров.
Возвращаемое значение
Возвращает примитивное значение объекта. Для объектов, не переопределяющих этот метод, возвращается сам объект. Для стандартных объектов:
- Number: числовое значение.
- String: строковое значение.
- Boolean: логическое значение.
- Date: количество миллисекунд с 1 января 1970 года.
- Array: массив (по умолчанию объект).
- Object: сам объект.
Базовые примеры использования valueOf()
Примеры с различными типами данных:
Числа
const num = new Number(42);
console.log(num.valueOf());42
Строки
const str = new String('Hello');
console.log(str.valueOf());Hello
Даты
const date = new Date('2023-01-01');
console.log(date.valueOf());1672531200000
Логические значения
const bool = new Boolean(false);
console.log(bool.valueOf());false
Объекты по умолчанию
const obj = {name: 'Test'};
console.log(obj.valueOf());{ name: 'Test' }Похожие функции в JavaScript
Метод toString()
Возвращает строковое представление объекта. Используется, когда нужна строка, а не примитивное значение. Часто вызывается автоматически при конкатенации.
Метод toPrimitive()
Символ Symbol.toPrimitive позволяет переопределить преобразование объекта в примитив. Используется для полного контроля над преобразованиями.
Метод Number() и String()
Функции явного преобразования типов. Предпочтительны, когда нужно явно указать тип преобразования.
Когда что использовать
Типичные ошибки при использовании valueOf()
Ожидание преобразования неопределенных свойств
const obj = {value: undefined};
obj.valueOf = () => this.value;
console.log(obj + 1);NaN
Рекурсивный вызов valueOf()
const obj = {};
obj.valueOf = () => obj;
console.log(obj + 1);TypeError: Cannot convert object to primitive value
Игнорирование приоритета методов
JavaScript может предпочитать toString() перед valueOf() в строковом контексте.
const obj = {
valueOf: () => 42,
toString: () => '100'
};
console.log('Result: ' + obj);Result: 100
Изменение встроенных прототипов
Number.prototype.valueOf = () => 999;
console.log(new Number(5) + 1);1000
Такие изменения нарушают ожидаемое поведение.
Изменения в последних версиях JavaScript
Метод valueOf() остаётся стабильным в спецификации ECMAScript. Существенных изменений в его работе не было. Однако, с введением символов в ES6 появился метод Symbol.toPrimitive, который имеет более высокий приоритет при преобразовании объектов в примитивы.
В современных версиях JavaScript рекомендуется использовать Symbol.toPrimitive для сложных сценариев преобразования, так как он предоставляет больше контроля через параметр hint.
Расширенные примеры использования valueOf()
Переопределение valueOf() в пользовательских объектах
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
valueOf() {
return Math.sqrt(this.x ** 2 + this.y ** 2);
}
}
const v1 = new Vector(3, 4);
const v2 = new Vector(6, 8);
console.log(v1 + v2);15
Использование вместе с toString()
const gameScore = {
score: 0,
valueOf() { return this.score; },
toString() { return `Score: ${this.score}`; }
};
gameScore.score = 150;
console.log(gameScore + 50);
console.log('Result: ' + gameScore);200 Result: Score: 150
Сравнение объектов через valueOf()
const age1 = new Number(25);
const age2 = new Number(30);
console.log(age1 > age2);
console.log(age1 + age2);false 55
Кастомные математические операции
const Money = {
value: 100,
currency: 'USD',
valueOf() {
return this.value;
}
};
console.log(Money * 2);
console.log(Money + 50);200 150
Работа с датами и временем
const start = new Date('2023-01-01');
const end = new Date('2023-12-31');
const difference = end.valueOf() - start.valueOf();
const days = difference / (1000 * 60 * 60 * 24);
console.log(days);364
Имитация перечисления с valueOf()
const Status = {
ACTIVE: {value: 1, toString: () => 'Active'},
INACTIVE: {value: 0, toString: () => 'Inactive'}
};
Status.ACTIVE.valueOf = () => 1;
Status.INACTIVE.valueOf = () => 0;
console.log(Status.ACTIVE + Status.INACTIVE);
console.log('Status: ' + Status.ACTIVE);1 Status: Active
Аналоги в других языках программирования
Python: методы __int__, __float__, __str__
Python использует специальные методы для преобразования типов.
class MyNumber:
def __init__(self, value):
self.value = value
def __int__(self):
return self.value
num = MyNumber(42)
print(int(num))42
PHP: магический метод __toString()
PHP преобразует объекты в строки через магический метод.
class MyClass {
public function __toString() {
return 'string representation';
}
}
$obj = new MyClass();
echo $obj;string representation
C#: методы ToString(), Convert
C# предоставляет стандартный интерфейс IConvertible.
int num = 42;
string str = num.ToString();
Console.WriteLine(str);42
MySQL: функции CAST() и CONVERT()
Явное преобразование типов в запросах.
SELECT CAST('123' AS SIGNED);123
Основные отличия
В отличие от JavaScript, где valueOf() часто вызывается неявно, в других языках обычно требуется явное преобразование типов.