| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Equality_comparisons_and_sameness | [Back] [Original] |
Get to know MDN better
Esta pgina ha sido traducida del ingls por la comunidad. Aprende ms y nete a la comunidad de MDN Web Docs.
Existen cuatro algoritmos de igualdad en ES2015:
==)===): utilizada por Array.prototype.indexOf, Array.prototype.lastIndexOf, y case-matching%TypedArray% y ArrayBuffer, as como por las operaciones Map y Set, y tambin por String.prototype.includes y Array.prototype.includes desde ES2016JavaScript proporciona tres operaciones distintas para comparar la igualdad de dos elementos:
Object.is proporciona SameValue (nuevo en ES2015).Elegir una u otra operacin depende del tipo de comparacin que se est buscando realizar.
Explicndolo de manera concisa, un doble igual lleva a cabo una conversin de tipo (cast) cuando se comparan dos cosas; el triple igual hace lo mismo pero sin realizar ninguna conversin de tipo (cast) (simplemente devuelve falso si los tipos de los elementos a comparar son diferentes); Y Object.is funciona de la misma manera que el triple igual pero hace una gestin especial de NaN, -0 y +0 de tal manera que los dos ltimos no son iguales mientras que Object.is(NaN, NaN) nos devolver true. (Si comparamos NaN con NaN de manera ordinaria , por ejemplo usando el doble igual o el triple igual, nos devolver false, ya que la especificacin IEEE 754 as lo dice). Hay que darse cuenta de que la distincin entre todas estas posibilidades tiene que ver con como se manejan los tipos primitivos; ninguna de ellas compara si los parmetros son similares en relacin a su estructura. Para comparar dos objectos no primitivos , x e y, que tengan la misma estructura pero que sean objetos diferentes entre ellos, todos los casos anteriormente descritos devolvern false.
===
Object.is o el igual triple
===El operador igualdad estricta compara la igualdad de dos valores. Ninguno de estos valores se convierte de manera implcita antes de ser comparado. Si los valores tienen tipos diferentes son considerados diferentes. Por el contrario, si los valores tienen el mismo tipo y no son nmeros, son considerados iguales si tienen el mismo valor. Finalmente, si ambos valores son nmeros, son considerados iguales si ambos no son NaN y tienen el mismo valor, o si uno es +0 y otro -0.
var num = 0;
var obj = new String("0");
var str = "0";
var b = false;
console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true
console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false
La igualdad estricta es casi siempre el operador igualdad ms adecuado. Para todos los valores, excepto para los nmeros, utiliza la semntica obvia: un valor slo es igual as mismo. Para nmero usa una semntica ligeramente diferente para paliar dos casos lmites diferentes. El primero es que usando nmero en coma flotante el cero puede ser positivo o negativo. Esto es til para representar ciertas soluciones matemticas, pero en la mayora de las situaciones no nos importa esa diferencia entre +0 y -0. La igualdad estricta los trata como un nicomvalor. El segundo caso tiene que ver con que los nmero en coma flotante incluyen el concepto NaN (Not a Number) como un posible valor para representar la solucin a ciertos problemas matemticos mal definidos, por ejemplo la adicin de un infinito negativo a un infinito positivo. La igualdad estricta trata NaN como desigual con cualquier otro valore incluyendo a s mismo. (El nico caso en el que x !== x es verdades en cuando x is NaN).
El operador igualdad dbil compara la igualdad de dos valores despus de convertir ambos valores a un tipo de datos comn. Tras la conversin , la comparacin que se lleva a cabo funciona exactamente como ===. La igual dbil es una igualdad simtrica: A == B tiene una semtica idntica a B == A para cualquier valor que tengan A y B ( excepto por el orden de las .conversiones de tipo aplicadas)
Para los operandos de varios tipos funciona de la siguiente manera:
| Operando B | |||||||
|---|---|---|---|---|---|---|---|
| Undefined | Null | Number | String | Boolean | Object | ||
| Operando A | Undefined | true |
true |
false |
false |
false |
false |
| Null | true |
true |
false |
false |
false |
false |
|
| Number | false |
false |
A === B |
A === ToNumber(B) |
A === ToNumber(B) |
A == ToPrimitive(B) |
|
| String | false |
false |
ToNumber(A) === B |
A === B |
ToNumber(A) === ToNumber(B)
|
A == ToPrimitive(B) |
|
| Boolean | false |
false |
ToNumber(A) === B |
ToNumber(A) === ToNumber(B)
|
A === B |
ToNumber(A) == ToPrimitive(B)
|
|
| Object | false |
false |
ToPrimitive(A) == B |
ToPrimitive(A) == B |
ToPrimitive(A) == ToNumber(B)
|
A === B |
|
En la tabla previa, ToNumber(A) intenta convertir su argumento a nmero antes de realizar la compracin. Su comportamiento es equivalente a +A (el operador unario +). ToPrimitive(A) intenta convertir su objeto argumento a un valor de tipo primitivo realizando varias secuencias de invocaciones A.toString y A.valueOf en A.
Tradicionalmente, y de acuerdo con la especificacin ECMAScript, todos los objetos son dbilmente desiguales comparndolos con undefined y null. Pero algunos nevegadores permiten que una cantidad muy limitada de clases de objetos (especifcamente , el objeto documento.all para todas las pginas), en algunos contextos, puedan actuar como si emularan el valor undefined. En ese contexto se evala como verdadero las igualdades dbiles null == A y undefined == A, s y slo s, A es un objecto que emula undefined. En cualquier otro caso la igual dbil no ser verdadera con undefined o null.
var num = 0;
var obj = new String("0");
var str = "0";
var b = false;
console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true
console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true
// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);
Algunos desarrolladores consideran que nunca es una buena idea usar este tipo de igualdad, la igualdad dbil. El resultado cuando se usa la igualdad estricta es ms fcil de predecir y , como no hay coercin de tipos durante la evaluacin, es con casi total seguridad ms rpida.
La igualdad Same-value se encarga de un ltimo caso de uso: determinar si dos valores son funcionalmente idnticos en todos los contextos. (Este caso de uso es un caso de ejemplo del Liskov substitution principle.) Un ejemplo de esto ocurre cuando se intenta hacer mutable una propiedad inmutable.
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
value: -0,
writable: false,
configurable: false,
enumerable: false,
});
function attemptMutation(v) {
Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
Object.defineProperty que lanzar una excepcin cuando se intente cambiar una propiedad inmutable la cambiar, pero no har nada si al solicitar el cambio actual . Si v es -0, no ha sido solicitado ningn cambio y no se lanzar ningn error. Pero si v es +0, Number . NEGATIVE_ZERO no tendr ms su valor inmutalbe. Internamente, al redefinir una propiedad inmutbale, el nuevo valor se compara con el valor actual usando la igualdad same-value.
El mtodo Object.is nos proporciona la igualdad same-value.
Similar a la igualdad same-value, pero +0 y -0 son considerados iguales.
En la especificacin ES5, la comparacin == queda descrita en Section 11.9.3, The Abstract Equality Algorithm. La comparacin === en 11.9.6, The Strict Equality Algorithm. (Bscala y leela, son breves y fciles de leer. Nota: lee el algoritmo de la igualdad estricta primero.) ES5 tambin describe, en Section 9.12, The SameValue Algorithm para uso interno del motor JS. Es, en su mayora igual que el algoritmo de igualdad estricto, excepto porque 11.9..6.4 y 9.12.4 difieren en cmo tratar los Numbers. ES2015 simplemente propone exponer este algoritmo mediante el uso deObject.is.
Podemos ver con el igual doble y el triple que, con la excepcin de hacer con antelacin una comprobacin de tipo en 11.9.6.1, el algorimto de igualdad estricta es un subconjunto del algorimot de igualdad abstracta porque 11.9.6.2-7 se corresponde con 11.9.3.1a-f.
Antes de ES2015, podamos haber dicho sobre el igual doble y el igual triple que uno es una versin mejoradad del otro. Por ejemplo, alguien podra decir que el igual doble es una versin extendida del igual triple ya que el primero hace todo lo que hace el segundo pero aadiendo la conversin de operadores. Por ejemplo 6 == "6". (De manera alternativa alguien podra decir que el igual doble es la base y que el igual triple es una versin mejorada, ya que requiere que los dos operadores sean del mismo tipo y, por lo tanto, aade una restriccin adicional. Qu afirmacin es mejor para entender el modelo depende en tu punto de vista).
Sin embargo. esta manera de pensar sobre los operadores de igualdad proporcionados de manera nativa no es un modelo en el que podamos encuadrar la versin ES2015 de Object.isno es simplemente ms dbil que el doble igual o ms estricto que el triple igual, ni tampoco ocupa un lugar intermedio (por ejemplo siendo a la vez ms estricto que el igual doble y ms dbil que el igual triple). Podemos ver en la tabla inferior que esto se debe a la manera en la que Object.ismaneja NaN. Fjate que si Object.is(Nan, Nan) evaluara a falso podramos decir que que se encuadra dentro de la escala dbil /estricta como algo ms estricto que el triple igual, como un operador que distigue entre +0 y -0. Sin embargo en el manejo de NaNesto no es cierto. Simplemente debemos considerar Object.isen trminos de sus caractersticas especficas y no en relacin a su debilidad o rigidez dentro del especto de los operadores de igualdad.
| x | y | == |
=== |
Object.is |
|---|---|---|---|---|
undefined |
undefined |
true |
true |
true |
null |
null |
true |
true |
true |
true |
true |
true |
true |
true |
false |
false |
true |
true |
true |
"foo" |
"foo" |
true |
true |
true |
{ foo: "bar" } |
x |
true |
true |
true |
0 |
0 |
true |
true |
true |
+0 |
-0 |
true |
true |
false |
0 |
false |
true |
false |
false |
"" |
false |
true |
false |
false |
"" |
0 |
true |
false |
false |
"0" |
0 |
true |
false |
false |
"17" |
17 |
true |
false |
false |
[1,2] |
"1,2" |
true |
false |
false |
new String("foo") |
"foo" |
true |
false |
false |
null |
undefined |
true |
false |
false |
null |
false |
false |
false |
false |
undefined |
false |
false |
false |
false |
{ foo: "bar" } |
{ foo: "bar" } |
false |
false |
false |
new String("foo") |
new String("foo") |
false |
false |
false |
0 |
null |
false |
false |
false |
0 |
NaN |
false |
false |
false |
"foo" |
NaN |
false |
false |
false |
NaN |
NaN |
false |
false |
true |
Object.is o el igual tripleAdems de como trata NaN, generalmente, la nica vez en la que Object.is posee un comportamiento especial hacia los ceros puede resultar de inters para usar ciertos esquemas de meta-programacin, sobre todo en relacin a los descriptores de porpiedades cuando es deseable que nuestro trabajo replique algunas de las caractersticas de Object.defineProperty. Si en tu situacin no requiere de esto, lo mejor es evitar Object.isy usar ===.Incluso si entre tus requisitos est poseer que la comparacin entre dos valores NaNsea verdadera, generalmente es ms fcil hacer un caso especial para ello (usando el mtodo isNaNque est disponible en versiones previas de ECMAScript) que calcular cmo la operaciones van afectar a los posibles signos de los valores cero en tu comparacin.
Aqu podemos ver una lista exhaustiva de los mtodo y operadores nativos que pueden distinguir entre -0 y +0 en tu cdigo:
- (unary negation)Obviamente negar 0 genera -0. Pero al abstraccin de una expresin puede causar que un valor -0 se cuele sin darte cuenta Consideremos el siguiente ejemplo:
let stoppingForce = obj.mass * -obj.velocity;
Si obj.velocity is 0 (o se calcula como 0), se inserta -0 en ese lugar y este valor se propaga a stoppingForce.
Math.atan2Empty
Math.ceilEmpty
Math.powEmpty
Math.roundSe puede introducir un -0 dentro de una expresin como valor de retorno en estos mtodo, incluso cuando -0 no sea uno de los parmetros. Por ejemplo usando Math.pow para elevar -Infinity a cualquier potencia negativa, los exponentes impares se evaluarn como -0. Consulta la documentacin para ms detalles sobre cada uno de los mtodos.
Math.floorEmpty
Math.maxEmpty
Math.minEmpty
Math.sinEmpty
Math.sqrtEmpty
Math.tanEs posible obtener, en algunos casos, -0 como valor de retorno de estos mtodos cuando -0 sea uno de los parmetros Por ejemplo Math.min(-0, +0) devuelve -0. Consulta la documentacin para ms detalles sobre cada uno de los mtodos.
~Empty
<<Empty
>>Cada uno de estos operadores usa el algoritmo ToInt32 de manera interna. Como slo hay un representacion de 0 para el intero de 32-bit interno. -0 no sobrevivir a la operacin inversa. Por ejemplo Object.is(~~(-0), -0) y Object.is(-0 << 2 >> 2, -0) devolvern false.
Confiar en Object.is cuando no hay que tener en cuenta el signo de los ceros puede ser peligroso. Por supuesto para el caso contrario har exactamente lo deseado.
Esta pgina se modific por ltima vez el 24 jun 2025 por colaboradores de MDN.
Partes de este contenido son 19982026 de colaboradores individuales de mozilla.org. Contenido disponible bajo una licencia Creative Commons.
| Web Proxy Viewer | New URL | Original Page |