Object.prototype.valueOf()
Метод valueOf()
(значення) примірників Object
перетворює значення this
на об'єкт. Очікується, що цей метод перевизначений похідними об'єктами задля їх власної логіки перетворення типів.
Спробуйте його в дії
Синтаксис
valueOf()
Параметри
Жодних.
Повернене значення
Значення this
перетворене на об'єкт.
[!NOTE] Щоб
valueOf
був корисним під час перетворення типів, він мусить повертати примітив. Через те, що всі примітивні типи мають власні методиvalueOf()
, загаломaPrimitiveValue.valueOf()
не закликаєObject.prototype.valueOf()
.
Опис
JavaScript викликає метод valueOf
для перетворення об'єкта на примітивне значення. Закликати valueOf
власноруч доводиться рідко; його автоматично закликає JavaScript, коли зустрічає об'єкт у місці, де очікується примітив.
Цей метод у першу чергу викликається алгоритмами зведення до числового значення та зведення до примітива, однак зведення до рядка у першу чергу викликає toString()
, а toString()
, із високою імовірністю, поверне рядкове значення (навіть у базовій реалізації Object.prototype.toString()
), тож valueOf()
у цьому випадку зазвичай не викликається.
Усі об'єкти, що успадковують від Object.prototype
(тобто всі, крім null
-прототипних об'єктів), успадковують метод toString()
. Базова реалізація Object.prototype.valueOf()
навмисно зроблена непридатною: вона повертає об'єкт, тож повернене нею значення ніколи не буде використано жодним алгоритмом зведення до примітива. Чимало вбудованих об'єктів перевизначає цей метод, аби повертати відповідне примітивне значення. При створенні власного об'єкта можна перевизначити valueOf()
, аби викликався власний метод, щоб такий власний об'єкт міг бути перетворений на примітивне значення. Загалом, valueOf()
використовується для повертання значення, що є найсуттєвішим в об'єкті – на відміну від toString()
, це не обов'язково повинен бути рядок. Інший варіант: можна додати метод [Symbol.toPrimitive]()
, котрий дає змогу іще краще контролювати процес перетворення; такий об'єкт завжди матиме пріоритет над valueOf
і toString
, при будь-якому перетворенні типів.
Приклади
Вживання valueOf()
Базовий метод valueOf()
повертає саме значення this
, перетворивши його на об'єкт, якщо воно ним не є. Таким чином, таке повернене значення ніколи не вживається жодним алгоритмом перетворення на примітив.
const obj = { foo: 1 };
console.log(obj.valueOf() === obj); // true
console.log(Object.prototype.valueOf.call("primitive"));
// [String: 'primitive'] (об'єкт-обгортка)
Перевизначення valueOf для власних об'єктів
Можна створити функцію, що викликатиметься на місці усталеного методу valueOf
. Така функція не повинна приймати аргументи, адже їй не будуть передані жодні аргументи, коли її викличуть при перетворенні типів.
Наприклад, можна додати метод valueOf
власному класові Box
.
class Box {
#value;
constructor(value) {
this.#value = value;
}
valueOf() {
return this.#value;
}
}
При використанні такого коду, щоразу, коли об'єкт типу Box
вживатиметься в контексті, де він повинен бути представлений примітивним значенням (але не конкретно рядком), JavaScript автоматично викликатиме функцію, означену в коді вище.
const box = new Box(123);
console.log(box + 456); // 579
console.log(box == 123); // true
Метод valueOf
зазвичай закликається з боку JavaScript, але можна закликати й самотужки, отак:
box.valueOf();
Застосування до об'єктів унарного плюса
Унарний плюс виконує над своїм операндом зведення до числового значення, що для більшості об'єктів без [Symbol.toPrimitive]()
означає виклик їхніх методів valueOf()
. Проте якщо об'єкт не має власного методу valueOf()
, то базова реалізація призведе до ігнорування valueOf()
, і натомість використовуватиметься повернене значення toString()
.
+new Date(); // Поточна мітка часу; те саме, що й new Date().getTime()
+{}; // NaN (toString() повертає "[object Object]")
+[]; // 0 (toString() повертає рядок порожнього списку)
+[1]; // 1 (toString() повертає "1")
+[1, 2]; // NaN (toString() повертає "1,2")
+new Set([1]); // NaN (toString() повертає "[object Set]")
+{ valueOf: () => 42 }; // 42
Специфікації
Сумісність із браузерами
desktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
valueOf
|
Chrome Full support 1 | Edge Full support 12 | Firefox Full support 1 | Internet Explorer Full support 4 | Opera Full support 3 | Safari Full support 1 | WebView Android Full support 1 | Chrome Android Full support 18 | Firefox for Android Full support 4 | Opera Android Full support 10.1 | Safari on iOS Full support 1 | Samsung Internet Full support 1.0 | Deno Full support 1.0 | Node.js Full support 0.10.0 |