Conversión de Objeto a Primitivo en JavaScript

Ahora es el momento de averiguar qué sucederá si añades objetos obj1 + obj2, restas obj1 - obj2, o imprimes usando alert(obj). En tal caso, los objetos se auto-convertirán a primitivos, después de lo cual se llevará a cabo la operación. Aquí están las principales reglas para las conversiones numéricas, de cadena y booleanas de los objetos:

  • En general, los objetos se consideran true en una conversión booleana. Sólo existen las conversiones de cadena y numérica.
  • Las conversiones numéricas tienen lugar cuando se restan objetos o se aplican funciones matemáticas.
  • La conversión de cadena ocurre cuando se muestra un objeto como alert(obj) y en contextos similares.

ToPrimitive

Es posible mejorar la conversión de cadena y numérica. Para lograr ese objetivo, necesitas usar métodos de objeto únicos.

Observamos tres variantes de conversión de tipos, también conocidas como "indicaciones" que se describen en la especificación:

"string"

En caso de una conversión objeto-a-cadena, mientras se opera en un objeto que espera una cadena, como alert:

// output
alert(obj);

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

"number"

En caso de una conversión objeto-a-número, como cuando estás haciendo cálculos matemáticos:

// 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"

Ocurre raramente, en caso de que el operador no sepa con certeza qué tipo esperar. Por ejemplo, el binario + trabajará con ambos, números y cadenas. Si el binario + tiene un objeto como argumento, usará el "default" para convertirlo.

Cuando comparas un objeto usando == con un símbolo, número, o una cadena, no está claro qué conversión es mejor hacer. Por eso es mejor usar la indicación "default".

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

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

Los operadores de comparación mayor y menor <, > trabajan tanto con números como con cadenas. Pero, ten en cuenta que en este caso, se utiliza la indicación "number", no el "default", como en los ejemplos anteriores.

De todas formas, en la práctica, no necesitas recordar todos estos detalles, casi todos los objetos incorporados (la excepción es el objeto Date).

Para implementar la conversión, JavaScript necesita encontrar e invocar 3 métodos de objeto. Estos son:

  • Llamar a obj[Symbol.toPrimitive](hint) - un método que incluye una clave simbólica Symbol.toPrimitive. Si existen tales métodos,
  • En otros casos, cuando la indicación es "string", seguir intentando obj.toString() y obj.valueOf().
  • Si la indicación es "default" o "number", seguir intentando obj.valueOf() y obj.toString().

Symbol.toPrimitive

Lo primero que debes saber es que existe un método incorporado conocido como Symbol.toPrimitive. En general, puedes utilizarlo para nombrar tu método de conversión de la siguiente manera:

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

En el siguiente ejemplo, el objeto coche lo aplica:

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

Ahora es el momento de aprender acerca de los métodos toString y valueOf. No te sorprendas al descubrir que no se consideran como símbolos. Están entre los métodos más antiguos.

El principal propósito de estos métodos es proporcionar una manera "antigua" de ejecutar la conversión.

En el caso de no existir Symbol.toPrimitive JavaScript intentará encontrarlos en la siguiente secuencia:

  1. toString -> valueOf en caso de la indicación "string".
  2. valueOf -> toString en otros casos

Los métodos mencionados anteriormente devolverán un valor primitivo. Devolver un objeto por valueOf o toString significa que se ignora.

Un objeto incluye los métodos toString y valueOf de la siguiente manera:

  • El método toString devuelve "[object Object]".
  • El método valueOf devolverá el propio objeto.

Veamos este caso:

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

Por lo tanto, siempre que uses un objeto como una cadena, tendrás [object Object].

Los Tipos de Retorno

Lo primero y más importante que debes notar es que los métodos de conversión primitiva nunca devuelven el primitivo que se indicó. No puedes controlar si el método toString devuelve una cadena o si Symbol.toPrimitive devuelve "number".

Una cosa es obligatoria: los métodos mencionados arriba deben devolver un primitivo y nunca un objeto.

Conversiones Adicionales

Ya has aprendido que una amplia gama de operadores y funciones implementan conversiones de tipo. Por ejemplo, al multiplicar * convertirá los operandos en números.

En el caso de pasar un objeto como argumento, se pueden distinguir dos etapas:

  • El objeto se ha convertido en un primitivo.
  • En caso de que el primitivo resultante no sea del tipo adecuado, se convierte.

Echemos un vistazo a este ejemplo:

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

Aquí, como primer paso, el objeto se convierte en un primitivo mediante la multiplicación obj * 3. Posteriormente, "2" * 3 se transforma en 2 * 3.

Las cadenas serán concatenadas en la misma condición por el binario más ya que acepta una cadena. Aquí hay un ejemplo:

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

Resumen

La conversión de objeto a primitivo puede ser invocada automáticamente por una serie de funciones y operadores incorporados que esperan un primitivo como valor.

Tiene las siguientes tres indicaciones:

  1. "string" usado para alert así como otras operaciones que requieren una cadena;
  2. "number" (usado para matemáticas)
  3. "default"(no muchos operadores)

El algoritmo de la conversión es el siguiente:

  1. Ejecutar obj[Symbol.toPrimitive](hint) en caso de que exista un método
  2. En otros casos, cuando la indicación es "string" . ejecutar obj.toString() y obj.valueOf(), lo que exista
  3. En caso de que la indicación sea "default"o "number" . ejecutar obj.valueOf() y obj.toString(), lo que exista.

Hora del Cuestionario: ¡Pon a Prueba Tus Habilidades!

¿Listo para desafiar lo que has aprendido? Sumérgete en nuestros cuestionarios interactivos para una comprensión más profunda y una forma divertida de reforzar tu conocimiento.

¿Te resulta útil?