¿Qué significa la construcción x = x || ¿Quieres decir?

Resuelto opHASnoNAME asked hace 14 años • 12 respuestas

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'? varA veces también lo veo sin declaración.

opHASnoNAME avatar May 10 '10 17:05 opHASnoNAME
Aceptado

¿ 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, devuelve truey si el segundo valor es false, devuelve false.
  • Si el primer valor es true, siempre devuelve true, 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 ifla 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 xfuera falso, eitherXorYsería y. En este caso obtendría "Either x or y is truthy."si yfuera 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 || ysignifica. Si xes verdad, xestá asignado a x, por lo que en realidad no pasa nada; de lo contrario yse 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 undefinedo 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 falsecomo flagAparámetro (ya que es booleano, es decir, puede ser trueo false)? Se convertiría en true. En este ejemplo, no hay forma de establecerlo flagAen false.

Sería una mejor idea verificar explícitamente si flagAes undefinedasí:

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 .

Michał Perłakowski avatar Jan 10 '2016 16:01 Michał Perłakowski

Significa que el titleargumento 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 truesi cualquiera ao bes true. Entonces, si aes cierto, no es necesario verificarlo ben absoluto. Esto se llama evaluación booleana de cortocircuito, por lo que:

var title = title || "Error";

Básicamente comprueba si titlese evalúa como false. Si lo hace, "regresa" "Error", de lo contrario, regresa title.

cletus avatar May 10 '2010 11:05 cletus

Si el título no está configurado, utilice 'ERROR' como valor predeterminado.

Más genérico:

var foobar = foo || default;

Lee: Establecer foobar en fooo default. Incluso podrías encadenar esto muchas veces:

var foobar = foo || bar || something || 42;
ericteubert avatar May 10 '2010 10:05 ericteubert