Преобразование объекта JavaScript в примитив

Теперь пришло время узнать, что произойдет, если вы добавите объекты obj1 + obj2, вычтите obj1 - obj2, или напечатаете с помощью alert(obj). В таком случае, объекты будут автоматически преобразованы в примитивы, после чего будет выполнена операция. Здесь основные правила для числового, строковогои булевого преобразований объектов:

  • В общем, объекты считаются true при булевом преобразовании. Есть только строковые и числовые преобразования.
  • Числовые преобразования происходят при вычитании объектов или применении математических функций.
  • Строковое преобразование происходит, когда мы выводим объект как alert(obj) и в подобных контекстах.

ToPrimitive

Возможно улучшить строковое и числовое преобразование. Для достижения этой цели, вам нужно использовать уникальные методы объекта.

Мы рассматриваем три варианта типа преобразования, также известных как “hints”, которые описаны в спецификации:

"string"

В случае object-to-string преобразования, при работе с объектом, который ожидает строку, как alert:

// output
alert(obj);

// using object as a property key
anotherObj[obj] = 120;

"number"

В случае object-to-number преобразования, например, когда вы занимаетесь математикой:

// explicit conversion
let num = Number(obj);
// maths (except binary plus)
let n = +obj; // unary plus
let delta = obj1 - obj2;
// less/greater comparison
let greater = obj1 > obj2;

"default"

Это случается редко, если оператор не знает, какой тип ожидать. Например, бинарный + будет работать как с числами, так и со строками. Если у бинарного + есть объект в качестве аргумента, он будет использовать "default" для его преобразования.

Когда вы сравниваете объект с использованием == с символом, числом или строкой, не ясно, какое преобразование лучше сделать. Вот почему лучше использовать подсказку "default".

// binary plus uses the "default" hint
let total = obj1 + obj2;

// obj == number uses the "default" hint
if (car == 1) { ...
};

Операторы больше и меньше <, > также работают с числами и строками. Но обратите внимание, что в этом случае используется подсказка "number", а не "default", как в предыдущих примерах.

Тем не менее, на практике вам не нужно помнить все эти детали, почти все встроенные объекты (исключение - объект Date).

Для реализации преобразования, JavaScript должен найти и вызвать 3 метода объекта. Они таковы:

  • Вызов obj[Symbol.toPrimitive](hint) - метод, включающий символический ключ Symbol.toPrimitive. Если есть такие методы,
  • В других случаях, когда подсказка - "string", продолжайте попытки с obj.toString() и obj.valueOf().
  • Если подсказка - "default" или "number", продолжайте попытки с obj.valueOf() и obj.toString().

Symbol.toPrimitive

Первое, что вам следует знать, это то, что существует встроенный метод, известный как Symbol.toPrimitive. В общем, вы можете использовать его для обозначения вашего метода преобразования следующим образом:

obj[Symbol.toPrimitive] = function (hint) {
  // must return a primitive value
  // hint = one of "string", "number", "default"
};

В следующем примере объект car применяет его:

Javascript object symbol convert to primitive
let car = { name: "BMW", price: 30000, [Symbol.toPrimitive](hint) { console.log(`hint: ${hint}`); return hint == "string" ? `{name: "${this.name}"}` : this.price; } }; // conversions demo: console.log(car); // hint: string -> {name: "BMW"} console.log(+car); // hint: number -> 30000 console.log(car + 5000); // hint: default -> 35000

toString/valueOf

Теперь пришло время узнать о методах toString и valueOf. Не удивляйтесь, узнав, что они не считаются символами. Они относятся к самым древним методам.

Основная цель этих методов - это предоставить “ancient-style” способ выполнения преобразования.

В случае отсутствия Symbol.toPrimitive JavaScript попытается найти их в следующей последовательности:

  1. toString -> valueOf в случае подсказки “string”.
  2. valueOf -> toString в других случаях

Упомянутые выше методы принесут примитивное значение. Возвращение объекта valueOf или toString означает, что он игнорируется.

Объект включает методы toString и valueOf следующим образом:

  • Метод toString возвращает "[object Object]".
  • Метод valueOf вернет сам объект.

Давайте посмотрим на этот случай:

Javascript object valueOf -> toString
let site = { name: "W3Docs" }; console.log(site); // [object Object] console.log(site.valueOf() === site); // true

Таким образом, всегда, когда вы используете объект в качестве строки, у вас будет [object Object].

Типы возвращаемых значений

Прежде всего, вы должны отметить, что методы преобразования примитивов никогда не возвращают подсказанный примитив. Вы не можете контролировать, вернет ли метод toString строку или Symbol.toPrimitive возвращает "number".

Обязательным является одно условие: вышеупомянутые методы должны возвращать примитив, а не объект.

Дальнейшие преобразования

Вы уже узнали, что множество операторов и функций выполняют преобразование типов. Например, умножение * преобразует операнды в числа.

В случае передачи объекта в качестве аргумента можно выделить два этапа:

  • Объект был преобразован в примитив.
  • Если получившийся примитив не соответствует нужному типу, он преобразуется.

Давайте посмотрим на этот пример:

Javascript object toString method
let obj = { //toString is capable of handling all conversions in the absence of different methods toString() { return "2"; } }; console.log(obj * 3); // 6, the object is converted to primitive "2", after which a number is made by multiplication

Тут, на первом шаге, объект преобразуется в примитив умножением obj * 3. После этого, "2" * 3 преобразуется в 2 * 3.

Строки будут преобразовываться в одну строку бинарным плюсом так же, так как он принимает строку. Вот пример:

Javascript object toString method
let obj = { toString() { return "2"; } }; console.log(obj + 3); // 23 ("2" + 3), the object is converted to primitive returned a string => concatenation

Основное содержание

Преобразование из объекта в примитив может быть вызвано автоматически рядом встроенных функций и операторов, ожидающих примитив в качестве значения.

У него есть три подсказки:

  1. "string" используется для alert также как и другие операции, которые требуют строку;
  2. "number" (используется для математики)
  3. "default"( немногие операторы)

Алгоритм преобразования таков:

  1. Запустите obj[Symbol.toPrimitive](hint), если есть такой метод
  2. В других случаях, когда подсказка - "string" . исполняйте obj.toString() и obj.valueOf(), какой-то из которых есть
  3. В случае, когда подсказка - "default"или "number" . исполняйте obj.valueOf() и obj.toString(), какой-то из которых есть.

Время Викторины: Проверьте Свои Навыки!

отовы проверить свои знания? Погрузитесь в наши интерактивные викторины для более глубокого понимания и веселого способа закрепить знания.

Считаете ли это полезным?