¿Podemos usar un operador menos como operador de comparación?
No pude encontrar una situación como esta.
function sign(x) { return (x > 0) - (x < 0) || +x; }No actuará como un operador de comparaciones. Actuará como un operador matemático. Para este trabajo, JavaScript convierte el booleano resultante de x > 0 y x < 0 a cero o uno, luego realiza la resta.
Este es un código extraño, pero válido.
Hay dos pasos para describir aquí.
Como ya se señaló en la respuesta de Elia Soares , JavaScript convierte implícitamente la expresión booleana en números al hacer una resta. true se convertirá en 1 y false en 0.
console.log(+true); console.log(+false); let x = 20; console.log(+(x > 0)); console.log(+(x < 0)); entonces, hacer (x > 0) - (x < 0) significa:
Si x es positivo, obtenemos 1 - 0 , lo que da 1 .
Si x es negativo, obtenemos 0 - 1 , lo que da -1 .
Si x es cero, obtenemos 0 - 0 , lo que da 0.
Esto ya parece bueno para crear una función de sign(x) como se espera normalmente .
Sin embargo, también considere undefined en esta fórmula: cualquier comparación dará false , por lo que la resta anterior dará cero.
Eso es un poco peligroso, podría ser que olvidó asignar un valor a la variable, que es un error común cuando escribe código.
Por eso el || +x Se agregó || +x .
|| en javascript significa:
Evalúa el lado izquierdo. Si es cierto , devuelve el lado izquierdo. De lo contrario, devuelva el lado derecho.
+1 y -1 son verdaderos y 0 es falso , por lo que la expresión completa (x > 0) - (x < 0) || +x se evaluará como +x si y solo si la resta da cero.
Si x es cero, seguirá dando +0, que es 0.
Si x es null , esto dará +null que es 0.
Si x no está undefined , dará +undefined , que es NaN .
Obtener un NaN en su cálculo hará que rápidamente todos sus resultados posteriores sean NaN , advirtiéndole que había algo indefinido que probablemente olvidó.
Tenga en cuenta que +x aún se evalúa como 0 si x es null o cadena vacía '' , por lo que este código no cambiará el resultado cero (quizás inesperado) para esos casos especiales.