Desafio JavaScript
Comparação com Object.is e coerção
Enunciado
Crie uma função comparar(a, b) que retorna um objeto com três propriedades: frouxa (resultado de a == b), estrita (resultado de a === b) e objectIs (resultado de Object.is(a, b)). Teste com pares de valores que evidenciem as diferenças: NaN e NaN, -0 e 0, '1' e 1, null e undefined, [] e [].
Requisitos
- A função deve retornar um objeto com as chaves
frouxa,estritaeobjectIs. - Imprima os resultados para cada par no formato
a, b => { frouxa: ..., estrita: ..., objectIs: ... }. - Use
Object.iscorretamente, sem implementar manualmente.
Código inicial
// Complete a função comparar
function comparar(a, b) {
// retorne um objeto com frouxa, estrita e objectIs
}
// Teste com os pares
Saída esperada
NaN, NaN => { frouxa: false, estrita: false, objectIs: true }
-0, 0 => { frouxa: true, estrita: true, objectIs: false }
'1', 1 => { frouxa: true, estrita: false, objectIs: false }
null, undefined => { frouxa: true, estrita: false, objectIs: false }
[], [] => { frouxa: false, estrita: false, objectIs: false }
Ver dica
Para representar os valores na saída, use uma função auxiliar que trate NaN, -0, arrays e strings de forma legível.
Mostrar solução
// Função que compara dois valores de três formas
function comparar(a, b) {
return {
frouxa: a == b, // igualdade frouxa (com coerção)
estrita: a === b, // igualdade estrita (sem coerção)
objectIs: Object.is(a, b) // igualdade SameValue
};
}
// Função auxiliar para representar valores na saída
function representar(v) {
if (typeof v === 'string') return `'${v}'`;
if (Array.isArray(v)) return '[]';
if (Object.is(v, -0)) return '-0';
if (Number.isNaN(v)) return 'NaN';
if (v === null) return 'null';
if (v === undefined) return 'undefined';
return String(v);
}
// Pares de valores para testar
const pares = [
[NaN, NaN],
[-0, 0],
['1', 1],
[null, undefined],
[[], []]
];
// Itera sobre os pares e imprime os resultados
for (const [a, b] of pares) {
const r = comparar(a, b);
console.log(`${representar(a)}, ${representar(b)} => { frouxa: ${r.frouxa}, estrita: ${r.estrita}, objectIs: ${r.objectIs} }`);
}
Passo a passo
- A função
compararrecebe dois valores e retorna um objeto com três propriedades:frouxa,estritaeobjectIs. frouxausa==, que aplica coerção de tipos antes de comparar.estritausa===, que compara tipo e valor sem conversão.objectIsusaObject.is, que é como===mas trataNaNcomo igual a si mesmo e diferencia-0de0.- A função
representarformata valores para a saída: strings entre aspas, arrays como[],-0como'-0',NaNcomo'NaN', etc. - O array
parescontém os cinco pares pedidos. - Usamos
for...ofcom desestruturação[a, b]para percorrer os pares. - Para cada par, chamamos
comparare imprimimos o resultado formatado.
Por que funciona
Object.is é uma operação de igualdade SameValue, definida na especificação ECMAScript. Ela se comporta como === para a maioria dos casos, mas duas diferenças importantes: Object.is(NaN, NaN) é true (enquanto NaN === NaN é false) e Object.is(-0, 0) é false (enquanto -0 === 0 é true). Isso torna Object.is útil para comparar valores de forma mais precisa, especialmente ao lidar com NaN e zeros com sinal.
Erros comuns
- Achar que
Object.isé sempre igual a===. Ele difere paraNaNe-0. - Usar
==para compararnulleundefinede achar que é um erro. Na verdade,null == undefinedétruepor definição, masnull === undefinedéfalse. - Esquecer que arrays e objetos são comparados por referência.
[] === []éfalseporque são objetos diferentes, mesmo que vazios.Object.is([], [])também éfalse. - Tentar representar
-0comString(-0), que retorna'0'. UseObject.is(v, -0)para detectar.
Outra forma de resolver
Você pode usar Number.isNaN e Object.is para detectar casos especiais, mas a função representar já cobre isso. Para comparar arrays por conteúdo, seria necessário uma função de comparação profunda, mas isso foge do escopo deste exercício.
Saída esperada
NaN, NaN => { frouxa: false, estrita: false, objectIs: true }
-0, 0 => { frouxa: true, estrita: true, objectIs: false }
'1', 1 => { frouxa: true, estrita: false, objectIs: false }
null, undefined => { frouxa: true, estrita: false, objectIs: false }
[], [] => { frouxa: false, estrita: false, objectIs: false }