post thumbnail

JavaScript Desmitificado: Coerción parte 1

Publicado Por: Oscar González, El 31/03/2014


Detalles del Curso:

Dificultad: Heroe

Duración: 10 min


Más artículos en JavaScript Desmitificado

Este es el artículo Coerción parte 1 de la serie JavaScript Desmitificado - Mostrar todos

  1. Objetos
  2. Funciones
  3. Clausuras (closures)
  4. Coerción parte 1
  5. Coercion Parte 2
  6. Concurrencia
  7. Calidad

Hoy les voy a hablar de uno de los temas más profundos y menos comentados de Javascript, la coerción.

Según el diccionario de la Real Academia Española, la coerción es la "presión ejercida sobre alguien para forzar su voluntad o su conducta", también se entiende por "represión, inhibición, restricción". En el caso de Javascript se explica como la acción de forzar a los objetos de un tipo a actuar como si fueran de otro. Esto no debe ser confundido con conversión de tipos, que es la conversión explícita de un tipo de dato en otro.

Lo más singular es que Javascript aplica coerción frente a nuestras narices sin nosotros darnos cuenta. Veamos algunos casos comunes, en los que esto ocurre:


Coerción a String

Para concatenar strings usamos el operador unitario (+, -, *, /), incluso lo usamos para concatenar strings con variables numéricas o números explícitos para formar mensajes más complejos.

console.log('Tengo ' + 10 + ' elefantes'); // => Tengo 10 elefantes

En este caso Javascript forza al 10 a actuar como un string. Esto suena muy simple dicho de esta manera, el funcionamiento interno es el siguiente: Javascript llama a la función toString(). Esta función es parte de todos los objetos en Javascript ya que es heredada de Object. Si toString() no es capaz de retornar una representación primitiva (en este caso string), difiere la llamada a la función valueOf(), también heredada de Object. Si esta tampoco es capaz de retornar una representación primitiva, entonces lanza una "TypeError Exception".


Coerción a Numero

Seguimos con más aplicaciones mágicas del operador unario. El trabajo de este operador es convertir a numero el operando que le sigue.

console.log(+'50'); // => 50
console.log(3 * '10'); // => 30
console.log(5 - '10'); // => -5

Y al igual que la conversión de string se basa en la interacción con los métodos toString() o valueOf(), sin embargo en este caso los llama al revés, primero a valueOf y luego a toString().


Coerción de acuerdo al contexto

Algunos objetos en javascript pueden ser forzados a trabajar con operadores unarios.

Utilizando los métodos valueOf() y toString() el objeto siendo forzado retorna un valor que tenga sentido según sea su aplicación.

El ejemplo más famoso es el del objeto Date.

console.log(+new Date()); // => 1396200768041
console.log(20 + +new Date()); // => 1396200768061

Este caso puede ser util para realizar operaciones, sin embargo hay ocasiones en las que es más util una representación en string.

console.log('La fecha de hoy es: ' + new Date()); // => 'La fecha de hoy es: Sun Mar 30 2014 13:09:26 GMT-0430 (VET)'

Entonces, los objetos forzados tienen la capacidad de retornar un valor según el contexto en el que se encuentren. En este caso, un valor numérico cuando utiliza en operaciones numéricas, y una representación en string para concatenación con strings.


Coercion de objetos propios

Tal cual como se forza el objeto Date, se debería poder hacer con los objetos creados por uno mismo. Resulta no ser tan fácil.

var Song = function (name, duration) {
  this.name = name;
  this.duration = duration;
};

var mySong = new Song('R U Mine', 202);


console.log(+mySong); // => NaN
console.log("Duración: " + dollar); // => Duración: [object Object]

// Ninguna de las dos representaciones es util.
// Sobreescribamos toString() y valueOf()

Song.prototype.toString = function () {
  return this.name;
};

Song.prototype.valueOf = function () {
  return this.duration;
};

console.log(+mySong); // => 202
console.log(mySong + ''); // => 202
console.log([mySong] + ''); // 'R U Mine'

¿Por qué mySong + '' retorna el resultado de typeOf() en lugar del resultado de toString()?.

Javascript tiene problemas para poder determinar el valor por defecto de un objeto, necesita un indicio para poder decantar por un tipo, si no, asume que necesitas un numero. Es por eso que colocándolo entre corchetes (indicio) lo forza a string.


Comparación de tipos con coerción

El operador igual (=) también puede forzar los objetos a tipos primitivos mediante la prueba de equidad.

El presente ejemplo es extraído del libro "Expert Javascript" de Mark Daggett.

console.log([1] == 1); // => true

console.log([1] == "1"); // => true

console.log([{
    toString: function () {
        return 1;
}
}] == "1"); // => true

console.log([1] === 1); // => false

console.log([1] === "1"); // => false

console.log([{
  toString: function () {
    return 1;
  }
}] === "1"); // => false

Cierre

En la próxima parte veremos otros tipos más complejos de coercion, por ahora me despido con lo que tenemos hasta aquí.

Hasta la próxima.


¿Te ha gustado esta publicación?

Compártela:

Por Oscar González

Conoce más sobre este autor aquí


comments powered by Disqus