1. Introducción
En el desarrollo real, tanto los operadores de comparación como los operadores de congruencia se utilizan con frecuencia
En el caso de diferentes tipos en los dos lados, el operador de comparación obtiene el resultado de la comparación después de la conversión de tipo implícita.
Sin embargo, existen algunas dificultades en la conversión de tipos implícita de tipos de referencia. En el desarrollo real, un poco de descuido provocará errores
como:
[] == 0 // true
Por lo tanto, es una buena idea comprender qué hace la capa inferior
2 Conversión de tipos de referencia y tipos de datos básicos
En la conversión implícita, el tipo de referencia generalmente se convierte en un tipo de datos básico y luego se realiza la comparación.
El propósito de la conversión es solo uno: obtener el tipo de datos básico o el valor original
Generalmente se utilizan dos API al convertir tipos de datos de referencia: valueOf y toString
- El método valueOf se utiliza para convertir el objeto al valor original. Si el objeto no tiene un valor original, valueOf devolverá el objeto en sí. Rara vez necesita llamar al método valueOf usted mismo; JavaScript lo llamará automáticamente cuando encuentre un objeto con el valor original esperado
- El método toString devuelve una cadena que representa el objeto.
2.1 Objeto a encadenar
Vuelva a escribir el prototipo valueOf y toString para una verificación simple. El tiempo es limitado y la lógica puede no ser completamente rigurosa. Si tiene tiempo, puede escribir más casos de acuerdo con sus ideas.
const log = console.log
Object.prototype.toString = () => 'a'
Object.prototype.valueOf = () => 'b'
log(Object() == 'a') // false
log(Object() == 'b') // true
Object.prototype.toString = () => 'a'
log(Object() == 'a') // true
Llame a valueOf primero y luego a toString
2.2 Objeto a numerar
Object.prototype.toString = () => 1
Object.prototype.valueOf = () => 2
log(Object() == 1)
log(Object() == 2) // true
Llame a valueOf primero y luego a toString
2.3 Matriz a cadena
Array.prototype.toString = () => 'a'
Array.prototype.valueOf = () => 'b'
log([] == 'a') // false
log([] == 'b') // true
Llame a valueOf primero y luego a toString
Array.prototype.join = () => 'a'
log([] == 'a') // true
La llamada subyacente es unirse
En este punto, es fácil entender que [] == 0 es cierto como se menciona al principio del artículo.
- Se detecta que el tipo de referencia y el tipo básico se comparan, por lo que js convierte implícitamente el tipo de referencia al tipo básico y luego compara
- En la conversión implícita, valueOf se llama primero y, debido a que es una matriz, el resultado de la ejecución del método de combinación se devuelve en valueOf
- El problema se vuelve familiar '' == 0, devuelve verdadero
3 resumen
Tipo de referencia al tipo básico, el objetivo es conseguir que el valor original, la capa inferior es llamar valueOf primero y luego toString
proceso, si cualquier método obtiene el valor original, volverá, de lo contrario continuar con el siguiente método.
Si el original el valor nunca se obtiene, luego lanza una excepción