¿Qué significa la construcción x = x || ¿Quieres decir?
Estoy depurando algo de JavaScript y no puedo explicar qué ||
hace:
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
¿Por qué este tipo consume var title = title || 'ERROR'
? var
A veces también lo veo sin declaración.
¿ Qué es el operador de doble tubería ( ||
)?
El operador de doble tubería ( ||
) es el operador lógicoOR
. En la mayoría de los idiomas funciona de la siguiente manera:
- Si el primer valor es
false
, verifica el segundo valor. Si es asítrue
, devuelvetrue
y si el segundo valor esfalse
, devuelvefalse
. - Si el primer valor es
true
, siempre devuelvetrue
, sin importar cuál sea el segundo valor.
Básicamente funciona así:
function or(x, y) {
if (x) {
return true;
} else if (y) {
return true;
} else {
return false;
}
}
Si aún no lo entiendes, mira esta tabla:
| true false
------+---------------
true | true true
false | true false
En otras palabras, sólo es falso cuando ambos valores son falsos.
¿En qué se diferencia en JavaScript?
JavaScript es un poco diferente porque es un lenguaje de tipo flexible . En este caso significa que puede utilizar ||
el operador con valores que no sean booleanos. Aunque no tiene sentido, puedes usar este operador con, por ejemplo, una función y un objeto:
(function(){}) || {}
¿Qué pasa allí?
Si los valores no son booleanos, JavaScript realiza una conversión implícita a booleanos . Significa que si el valor es falso (p. ej 0
. ""
, null
, undefined
(consulte también Todos los valores falsos en JavaScript )), se tratará como false
; de lo contrario se trata como true
.
Entonces, el ejemplo anterior debería dar true
, porque la función vacía es verdadera. Bueno, no es así. Devuelve la función vacía. Esto se debe a que ||
el operador de JavaScript no funciona como escribí al principio. Funciona de la siguiente manera:
- Si el primer valor es falso , devuelve el segundo valor .
- Si el primer valor es verdadero , devuelve el primer valor .
¿Sorprendido? De hecho, es "compatible" con el ||
operador tradicional. Podría escribirse como la siguiente función:
function or(x, y) {
if (x) {
return x;
} else {
return y;
}
}
Si pasa un valor verdadero como x
, devuelve x
, es decir, un valor verdadero. Entonces, si lo usas más adelante en if
la cláusula:
(function(x, y) {
var eitherXorY = x || y;
if (eitherXorY) {
console.log("Either x or y is truthy.");
} else {
console.log("Neither x nor y is truthy");
}
}(true/*, undefined*/));
usted obtiene "Either x or y is truthy."
.
Si x
fuera falso, eitherXorY
sería y
. En este caso obtendría "Either x or y is truthy."
si y
fuera verdadero; de lo contrario obtendrías "Neither x nor y is truthy"
.
La pregunta real
Ahora que sabes cómo ||
funciona operador, probablemente puedas entender por ti mismo lo que x = x || y
significa. Si x
es verdad, x
está asignado a x
, por lo que en realidad no pasa nada; de lo contrario y
se asigna a x
. Se usa comúnmente para definir parámetros predeterminados en funciones. Sin embargo, a menudo se considera una mala práctica de programación , porque le impide pasar un valor falso (que no es necesariamente undefined
o null
) como parámetro. Considere el siguiente ejemplo:
function badFunction(/* boolean */flagA) {
flagA = flagA || true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Parece válido a primera vista. Sin embargo, ¿qué pasaría si pasara false
como flagA
parámetro (ya que es booleano, es decir, puede ser true
o false
)? Se convertiría en true
. En este ejemplo, no hay forma de establecerlo flagA
en false
.
Sería una mejor idea verificar explícitamente si flagA
es undefined
así:
function goodFunction(/* boolean */flagA) {
flagA = typeof flagA !== "undefined" ? flagA : true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Aunque es más largo, siempre funciona y es más fácil de entender.
También puede utilizar la sintaxis de ES6 para los parámetros de función predeterminados , pero tenga en cuenta que no funciona en navegadores más antiguos (como IE). Si desea admitir estos navegadores, debe transpilar su código con Babel .
Consulte también Operadores lógicos en MDN .
Significa que el title
argumento es opcional. Entonces, si llama al método sin argumentos, usará un valor predeterminado de "Error"
.
Es una abreviatura de escribir:
if (!title) {
title = "Error";
}
Este tipo de truco taquigráfico con expresiones booleanas también es común en Perl. Con la expresión:
a OR b
evalúa true
si cualquiera a
o b
es true
. Entonces, si a
es cierto, no es necesario verificarlo b
en absoluto. Esto se llama evaluación booleana de cortocircuito, por lo que:
var title = title || "Error";
Básicamente comprueba si title
se evalúa como false
. Si lo hace, "regresa" "Error"
, de lo contrario, regresa title
.
Si el título no está configurado, utilice 'ERROR' como valor predeterminado.
Más genérico:
var foobar = foo || default;
Lee: Establecer foobar en foo
o default
. Incluso podrías encadenar esto muchas veces:
var foobar = foo || bar || something || 42;