¿Qué es exactamente la coerción de tipo en Javascript?

122

¿Qué es exactamente la coerción de tipo en Javascript?

Por ejemplo, sobre el uso de en ==lugar de ===?

gespinha
fuente
21
(true == 1) => true/ (true === 1) => false.
VisioN
5
@VisioN tu comentario no ayuda en absoluto, estoy preguntando: "¿por qué" sucede eso?
gespinha
3
Sucede así porque JavaScript se desarrolló de esta manera. Mi comentario debería responder a su pregunta principal: ¿Qué es exactamente la coerción de tipo en Javascript?
VisioN
6
A través de YDJS: "Convertir un valor de un tipo a otro a menudo se denomina" conversión de tipos "cuando se hace explícitamente y" coerción "cuando se hace implícitamente (forzado por las reglas de cómo se usa un valor)". - github.com/getify/You-Dont-Know-JS/blob/master/…
mattLummus

Respuestas:

177

La coerción de tipos significa que cuando los operandos de un operador son de diferentes tipos, uno de ellos se convertirá en un valor "equivalente" del tipo del otro operando. Por ejemplo, si lo hace:

boolean == integer

el operando booleano será convertido a un número entero: falsese convierte en 0, truese convierte en 1. A continuación, los dos valores se comparan.

Sin embargo, si utiliza el operador de comparación ===sin conversión, no se produce dicha conversión. Cuando los operandos son de diferentes tipos, este operador devuelve falsey solo compara los valores cuando son del mismo tipo.

Barmar
fuente
1
¿Cómo puedo poner esto en una situación práctica? ¿No debería usar siempre ===cuando quiero comparar si un valor es igual a otro?
gespinha
1
Depende de lo que estés haciendo. Vea la pregunta vinculada.
Barmar
8
@GEspinha bueno, ese es el "arte" de usar un lenguaje de escritura suelta. Algunas personas piensan que sí y, en general, piensan que los lenguajes de tipo flexible son el flagelo del mundo de la programación. Sin embargo, si sabe lo que está haciendo, puede generar un código más corto y flexible.
Crayon Violent
2
@Barmar ¿También se aplica a > , <?
Royi Namir
2
Una excelente referencia y explicación sobre la coerción: github.com/getify/You-Dont-Know-JS/blob/master/…
Greg Bell
56

Comencemos con una breve introducción a los sistemas de tipos que creo que le ayudarán a comprender la idea general de la coerción de tipos.

El sistema de tipos de un idioma define reglas que nos dicen qué tipos de datos existen en ese idioma y cómo se pueden combinar utilizando diferentes operadores. Por ejemplo, una de esas reglas podría especificar que el operador más (+) solo actúa sobre números. Estas reglas existen principalmente para evitar que te dispares en el pie. Pero, ¿qué sucede cuando el programador rompe esa regla en el programa? No hay nada que impida que el programador escriba {} + {}o“hello” + 5 en un programa, incluso si el lenguaje no cree que esas expresiones tengan sentido.

Lo que finalmente sucede en esas situaciones depende de cuán estricto sea el lenguaje con respecto a sus reglas de tipo.

Un sistema de tipos de lenguajes a menudo tiene una de dos posiciones acerca de que usted rompe sus reglas:

  1. Di "¡Oye, eso no está bien!" e inmediatamente bloquee su programa.
  2. Di "No puedo hacer nada con {} ... pero puedo hacer algo con números" e intenta convertir {} en un número.

Los lenguajes con sistemas de tipos que toman la primera posición sobre sus reglas se conocen coloquialmente como lenguajes “fuertemente tipados”. Son estrictos sobre no dejarte romper sus reglas. Aquellos que adoptan el segundo enfoque (como JavaScript) se denominan lenguajes de "tipado débil" o "tipado flojo". Claro, puede romper las reglas, pero no se sorprenda cuando convierta el tipo de datos que describió en su programa a la fuerza para cumplir con sus reglas. Ese comportamiento se conoce como ... (redoble de tambores) ... tipo coerción .

Ahora veamos algunos ejemplos en JavaScript. Primero, comencemos con una expresión que no lleve a la coerción de tipos.

5 + 5

Usando el operador + con dos números que es perfectamente válido. El programa tratará + para significar "sumar" y felizmente sumará los dos números. No se necesita conversión.

Pero que pasa …

[] + 5

UH oh. En JavaScript, +puede significar agregar dos números o concatenar dos cadenas. En este caso, no tenemos ni dos números ni dos cadenas. Solo tenemos un número y un objeto. Según las reglas de tipo de JavaScript, esto no tiene sentido lógico. Dado que es indulgente con que rompas sus reglas, en lugar de fallar, intenta darle sentido de todos modos. Entonces, ¿qué hace JavaScript? Bueno, sabe cómo concatenar cadenas, por lo que convierte tanto [] como 5 en cadenas y el resultado es el valor de cadena “5”.

¿Cuál es el trato con los operadores de comparación ==y ===? ¿Por qué hay dos operadores de comparación?

==no es inmune al comportamiento de conversión de tipos de JavaScript. Expresiones como5 == “5” se evaluarán como verdaderas porque JavaScript intentará convertir una de ellas para comparar el mismo tipo de datos.

En muchos casos, eso no es deseable porque probablemente desee saber si algunos datos con los que está comparando son de un tipo diferente para poder decidir qué hacer al respecto. Ahí es donde ===entra el operador. Cuando utilice ===, no se llevará a cabo ninguna conversión de tipo. Por lo tanto, la expresión 5 === “5”se evaluará como falsa.

fideos chinos
fuente
4
gracias por una buena explicación, especialmente por "Un sistema de tipos de idiomas a menudo ocupa una de dos posiciones"
Humoyun Ahmad
1
Esta debería ser la respuesta aceptada, ya que muestra la coerción automática de tipos en múltiples facetas, no solo en el ejemplo de comparación ==. Esta respuesta hace un trabajo general mucho mejor al responder la pregunta y eliminar toda ambigüedad. Gracias por tomarse el tiempo para escribirlo.
el chad
6

En Python, si intenta agregar, digamos, cadenas y enteros, obtiene un error:

>>> "hi" + 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

Sin embargo, en JavaScript, no es así. El 10se convierte en una cadena:

> "hi" + 10
"hi10"

"Tipo coerción" es simplemente un nombre inapropiado para lo anterior. En realidad, ninguno de los lenguajes tiene "tipos" en el sentido de Java o C u otros lenguajes con sistemas de tipos estáticos. La forma en que los lenguajes tratan las interacciones entre los distintos valores no tipificados estáticamente es una cuestión de elección y convención.

Claudiu
fuente
1
Creo que hay un pequeño problema con el ejemplo que ha tomado. Lo que sugirió como ejemplo para JS funciona perfectamente con Java y C #. Entonces, de acuerdo con esta respuesta, si uno concluye que Java y C # admiten la coerción de tipo que no será del todo cierto ...
Romeo Sierra
3

déjame explicarte el tipo de coerción con el siguiente ejemplo

Type Coercion significa que Javascript automáticamente (sobre la marcha) convierte una variable de un tipo de datos a otro

Ej: 123 + "4"generalmente genera un error pero en Javascript debido a la coerción de tipo, da como resultado 1234una cadena

if(23 == "23"){
    console.log(" this line is inside the loop and is executed ");
}

En el código anterior, debido a la coerción de tipo, JavaScript piensa que 23(número) y "23"(cadena) son lo mismo. esto hace que la condición sea verdadera e imprime el archivo console.log

En el otro caso

if(23 === "23"){
   console.log(" this line is inside the loop and is NOT executed");
}

En ===caso de que Javascript no haga Type Coercion, ya que 23es un número y "23"es String y debido a que ===estos dos tipos de datos son diferentes y eso conduce a la condición falsa. No imprime el archivo console.log

En palabras simples

En este caso =, es un operador de asignación, que asigna valores como var a = 3;, etc.

(los operadores a continuación son para comparación)

En este caso, ==Javascript convierte / coacciona el tipo de datos a otro y luego lo compara.

En este caso, === Javascript no convierte / coacciona el tipo de datos

Para evitar errores y con fines de depuración ===se utiliza principalmente

Hágame saber la exactitud de la información anterior.

PRagh
fuente
2

¿Qué es la coerción?

La coerción de tipo en javascript ocurre cuando el motor Javascript tiene que realizar una determinada operación para la cual necesita que los datos estén en un cierto tipo. Cuando el motor encuentra datos en un tipo determinado que no es aplicable para la operación, entonces coacciona los datos en un tipo determinado. Esto es necesario porque las variables en javascript se escriben dinámicamente, lo que significa que a una variable determinada se le puede asignar un valor de cualquier tipo.

Ejemplo:


if(1){
  // 1 gets coerced to true
}


if(4 > '3') {
  // 3 gets coerced into a number
}


44 == "44"  // true, the string 44 gets converted to a nr

Coerción booleana:

En la coerción de JavaScript, todos los valores se convierten a, trueexcepto los siguientes valores, que se obligan a false:

console.log(!!"");         // false
console.log(!!0);          // false
console.log(!!null);       // false
console.log(!!undefined);  // false
console.log(!!NaN);        // false
console.log(!!false);      // false

También observe que en el ejemplo anterior que el doble! se utiliza el operador. Los ! El operador de marca convierte un valor en un booleano con el valor opuesto. Podemos usar este operador dos veces para convertir cualquier valor en un booleano.

Willem van der Veen
fuente
1

a == bsignifica que javascript se evaluará aen bfunción de si los valores se pueden evaluar por igual. Por ejemplo, false == 0evaluará verdadero porque 0 también es el valor de booleano falso. Sin embargo, false === 0evaluará falso porque estrictamente comparando, 0 no es el mismo valor físico que falso. Otro ejemplo es false == ''la comparación básicamente imprecisa frente a la comparación estricta, porque javascript es un lenguaje poco escrito. Es decir, javascript intentará convertir la variable basándose en el contexto del código, y esto tiene el efecto de igualar las cosas si no se comparan estrictamente. php también tiene este comportamiento.

Crayon violento
fuente
0 is not the same physical value as false. En mi opinión, físicamente falseestá exactamente 0en la memoria. Prefiero decir que son diferentes por tipo, ya que falsees booleano, mientras que 0es entero.
VisioN
1

La coerción de tipos es el proceso de convertir un valor de un tipo a otro (como cadena en número, objeto en booleano, etc.). Cualquier tipo, ya sea primitivo o un objeto, es un sujeto válido para la coerción de tipos. Para recordar, las primitivas son: número, cadena, booleano, nulo, indefinido + Símbolo (agregado en ES6).

Coerción implícita versus explícita La coerción de tipo puede ser explícita e implícita.

Cuando un desarrollador expresa la intención de convertir entre tipos escribiendo el código apropiado, como Number(value), se llama coerción explícita de tipos (o conversión de tipos).

Dado que JavaScript es un lenguaje de tipado débil, los valores también se pueden convertir entre diferentes tipos de forma automática y se denomina coerción de tipo implícita. Suele ocurrir cuando se aplica a los operadores de valores de diferentes tipos, como 1 == null, 2/’5', null + new Date(), o puede ser provocada por el contexto que rodea, al igual que con el if (value) {…}, donde se fuerza el valor booleano.

Un operador que no desencadena la coerción de tipo implícita es ===, que se denomina operador de igualdad estricta. Por ==otro lado, el operador de igualdad flexible hace tanto la comparación como la coerción de tipos si es necesario.

La coerción de tipo implícita es una espada de doble filo: es una gran fuente de frustración y defectos, pero también un mecanismo útil que nos permite escribir menos código sin perder la legibilidad.

Tres tipos de conversión La primera regla que debe saber es que solo hay tres tipos de conversión en JavaScript:

  • Encadenar
  • a booleano
  • Al numero

En segundo lugar, la lógica de conversión para primitivas y objetos funciona de manera diferente, pero tanto las primitivas como los objetos solo se pueden convertir de esas tres formas.

Comencemos primero con las primitivas.

Conversión de cadenas

Para convertir explícitamente valores en una cadena, aplique la función String (). La coerción implícita es activada por el operador binario +, cuando cualquier operando es una cadena:

String(123) // explicit
123 + ''    // implicit

Todos los valores primitivos se convierten en cadenas de forma natural, como es de esperar:

String(123)                   // '123'
String(-12.3)                 // '-12.3'
String(null)                  // 'null'
String(undefined)             // 'undefined'
String(true)                  // 'true'
String(false)                 // 'false'

La conversión de símbolos es un poco complicada, porque solo se puede convertir explícitamente, pero no implícitamente.

String(Symbol('my symbol'))   // 'Symbol(my symbol)'
'' + Symbol('my symbol')      // TypeError is thrown

Conversión booleana

Para convertir explícitamente un valor en booleano, aplique la Boolean()función. La conversión implícita ocurre en un contexto lógico o es activada por operadores lógicos ( || && !).

Boolean(2)          // explicit
if (2) { ... }      // implicit due to logical context
!!2                 // implicit due to logical operator
2 || 'hello'        // implicit due to logical operator

Nota: Los operadores lógicos como, por ejemplo, || and &&realizan conversiones booleanas internamente, pero en realidad devuelven el valor de los operandos originales, incluso si no son booleanos.

// returns number 123, instead of returning true
// 'hello' and 123 are still coerced to boolean internally to calculate the expression
let x = 'hello' && 123;   // x === 123

Tan pronto como solo haya 2 resultados posibles de conversión booleana: verdadero o falso, es más fácil recordar la lista de valores falsos.

Boolean('')           // false
Boolean(0)            // false     
Boolean(-0)           // false
Boolean(NaN)          // false
Boolean(null)         // false
Boolean(undefined)    // false
Boolean(false)        // false

Cualquier valor que no está en la lista se convierte en true, incluyendo object, function, Array, Date, tipo definido por el usuario, y así sucesivamente. Los símbolos son valores veraces. Los objetos vacíos y las matrices también son valores veraces:

Boolean({})             // true
Boolean([])             // true
Boolean(Symbol())       // true
!!Symbol()              // true
Boolean(function() {})  // true

Conversión numérica

Para una conversión explícita, simplemente aplique la Number()función, igual que hizo con Boolean()y String().

La conversión implícita es complicada porque se activa en más casos:

  • operadores de comparación (>, <, <=,> =)

  • operadores bit a bit (| & ^ ~)

  • operadores aritméticos (- + * /%). Tenga en cuenta que binary + no activa la conversión numérica, cuando cualquier operando es una cadena.

  • operador + unario

  • operador de igualdad suelto == (incluido! =).

    Tenga en cuenta que == no activa la conversión numérica cuando ambos operandos son cadenas.

    Número ('123') // explícito + '123' // implícito 123! = '456' // implícito 4> '5' // implícito 5 / nulo // implícito verdadero | 0 // implícito

Así es como los valores primitivos se convierten en números:

Number(null)                   // 0
Number(undefined)              // NaN
Number(true)                   // 1
Number(false)                  // 0
Number(" 12 ")                 // 12
Number("-12.34")               // -12.34
Number("\n")                   // 0
Number(" 12s ")                // NaN
Number(123)                    // 123
Tejas Savaliya
fuente
0
var str = 'dude';
console.log(typeof str); // "string"
console.log(!str); // false
console.log(typeof !str); // "boolean"

Ejemplo de una variable que se declara inicialmente como una cadena que se convierte en un valor booleano con el! operador

Señor P
fuente
3
Por favor, elabore su respuesta. Las respuestas de solo código no son realmente útiles.
cezar
3
personalmente me parece códigos únicos ejemplos sucinta, explica por sí mismo y muy útil, supongo que es una cuestión de opinión personal
Señor P
0

La coerción de tipos es el proceso de convertir un valor de un tipo a otro (como cadena en número, objeto en booleano, etc.). Cualquier tipo, ya sea primitivo o un objeto, es un sujeto válido para la coerción de tipos. Para recordar, las primitivas son: número, cadena, booleano, nulo, indefinido + Símbolo (agregado en ES6).

La coerción de tipo puede ser explícita e implícita.

Cuando un desarrollador expresa la intención de convertir entre tipos escribiendo el código apropiado, como Número (valor), se llama coerción explícita de tipos (o conversión de tipos).

Dado que JavaScript es un lenguaje de tipado débil, los valores también se pueden convertir entre diferentes tipos de forma automática y se denomina coerción de tipo implícita. Por lo general, sucede cuando aplica operadores a valores de diferentes tipos, como 1 == nulo, 2 / '5', nulo + nueva Fecha (), o puede activarse por el contexto circundante, como con if (valor) {… }, donde el valor se convierte en booleano.

aquí hay un ejemplo de coerción de tipo implícita:

true + false
12 / "6"
"number" + 15 + 3
15 + 3 + "number"
[1] > null
"foo" + + "bar"
'true' == true
false == 'false'
null == ''
!!"false" == !!"true"
[‘x’] == x
[] + null + 1
[1,2,3] == [1,2,3]
{}+[]+{}+[1]
!+[]+[]+![]
new Date(0) - 0
new Date(0) + 0

leer más: https://www.freecodecamp.org/news/js-type-coercion-explained-27ba3d9a2839/

Mahdi Salehian
fuente
-2

Si el tipo de datos no es igual entre sí, entonces Coercion Happen. como 3 == "3" o boolen == entero

ASAbir
fuente