11

Estoy viendo JavaScript y me topé con esto que no comprendo los objetos booleanos y los primitivos booleanos.

  1. ¿Utilizado un objeto booleano para compararlo en un if me dará false?

  2. ¿O por qué la documentacion de Gramatica y Tipos (MDN) dice que no se debe confundir con estas dos cosas?

    Literales Booleanos

    Los literales de tipo Booleanos tienen 2 valores posibles: true y false.

    NO confundir los valores primitivos Booleanos true y false con los valores true y false del Objeto Booleano. El objeto Booleano es un contenedor alrededor del tipo de dato Primitivo Booleano. Para más información revisa Booleano.

Mariano
  • 23,777
  • 20
  • 70
  • 102
sommer0123
  • 141
  • 3

3 Answers3

11

Los literales booleanos son sólo dos: true y false.

var a = true;
var b = false;

Por 'literal' se debe entender la representación de un valor en el mismo código fuente, en este sentido la variable a almacena un valor primitivo booleano que evalúa a verdadero mientras que la variable b almacena un valor primitivo booleano que evalúa a falso.

if(a) 
    alert("Verdadero"); //Imprime "Verdadero"
else
    alert("Falso");

Los objetos booleanos son un tipo de entidad que actúan como 'contenedores' de un valor booleano:

var o = new Boolean(false);

De acuerdo con la documentación, al ser creado un objeto Boolean puede tomar dos valores iniciales: falso o verdadero, dependiendo de los parámetros que se le pasen al construir el objeto. Los siguientes objetos booleanos tienen estado inicial falso:

var p = new Boolean();
var p = new Boolean(0);
var p = new Boolean(-0);
var p = new Boolean(null);
var p = new Boolean(false);
var p = new Boolean(undefined);
var p = new Boolean(NaN);
var p = new Boolean("");

así como a cualquier expresión que se pase como parámetro y evalúe a 0, -0, null, false, undefined, NaN o "". En cualquier otro caso, tendrá un estado inicial de verdadero.

Por otro lado, todo objeto en Javascript es susceptible de ser evaluado en un if, acudiendo nuevamente a la documentación, cualquier objeto cuyo valor no sea undefined o null evalúa a verdadero cuando se pasa en un if. Esto implica que a pesar que el estado del objeto booleano que se haya creado sea falso, este siempre evaluará a verdadero cuando se pase en un condicional if. Por lo tanto:

var name = "Daniel";
var edad = 24;
var programador = true;
var mujer = false;
var incognita;
var rico = new Boolean(false);

if(name) { console.log(name); } //Imprime "Daniel"
if(edad) { console.log(edad); } //Imprime 24
if(mujer) { console.log(mujer); } //No imprime nada, mujer es primitivo booleano y su valor es false
if(incognita) { console.log(incognita); } //No imprime nada, el valor por defecto de una variable creada es undefined y por lo tanto evalúa a false
if(rico) { console.log("Rico"); } //Imprime rico, a pesar que el valor del objeto es false, evalúa a verdadero en el condicional.
dwarandae
  • 2,459
  • 6
  • 18
  • 41
  • 1
    Para evitar la ambiguedad existe el operador === que compara ademas del valor el tipo de la variable. Entonces, si quiero estar seguro de que una variable es verdadera vs que un objeto exista, puedo hacer if(variable === true){...} – Juan Jul 10 '17 at 13:03
  • 6
    Cuidado @Juan con la interpretación de `===` (y de `==`). Por ejemplo `if(a==b)` y también `if(a===b)` darán falso aún cuando ambos sean objetos `Boolean` del mismo valor. – Emilio Platzer Jul 11 '17 at 00:19
4

La premisa básica es, siempre que sea posible usa un tipo de dato primitivo en lugar de un Objeto debido a que es el nivel más básico y por ende más eficiente.

  1. ¿Utilizado un objeto booleano para compararlo en un if me dará false?

Depende con qué y cómo lo compares, sin embardo si siempre lo usas como el único miembro de la expresión te dará true. Los detalles abajo.

¿O por qué la documentacion de Gramatica y Tipos (MDN) dice que no se debe confundir con estas dos cosas?

En el texto citado se incluye un enlace a un página que en español no existe pero en inglés sí: Boolean. En esta página dice

Any object of which the value is not undefined or null, including a Boolean object whose value is false, evaluates to true when passed to a conditional statement.

La traducción sería

Cualquier objeto cuyo valor no sea undefined o null, incluyendo un objeto Booleano cuyo valor es false, evalúa a true cuando es pasado a un enunciado condicional.

A continuación unos ejemplos de esto:

// Creamos un Objeto Booleano con valor falso.
var x = new Boolean(false);

// Comparación abstracta. Devuelve Verdadero
if(x == false){
  console.info('Verdadero');
} else {
  console.info('False');
}

// Comparación estricta. Devuelve Falso
if(x === false){
  console.info('Verdadero');
} else {
  console.info('Falso');
}

// Sin realizar una comparación. Devuelve verdadero.
if(x){
  console.info('Verdadero');
} else {
  console.info('Falso');
}

Un primitivo Booleano y un objeto Booleano no deben confundirse debido a que JavaScript convierte el tipo de los argumentos cuando estos no son del tipo requerido, que en un if se trata de un contexto Booleano.

En se la ECMAScript 2016, sobre ConditionExpression se indica:

NOTE
The grammar for a ConditionalExpression in ECMAScript is slightly different from that in C and Java, which each allow the second subexpression to be an Expression but restrict the third expression to be a ConditionalExpression. The motivation for this difference in ECMAScript is to allow an assignment expression to be governed by either arm of a conditional and to eliminate the confusing and fairly useless case of a comma expression as the centre expression.

A continuación un intento de traducir lo anterior:

NOTA La gramática para ContidionalExpression en ECMAScript es ligeramente diferente de aquella en C y Java, donde cada una permite que la segunda subexpresión sera una Expresión but restringe la tercera expresión a ser una ConditionalExpression. La motivación de esta diferencia en ECMAScript es permitir que una expresión de asignación sea gobernada por cualquier brazo de un condicional y para eliminar la confusión y prácticamente casa inútil de una expresión coma como el centro de la expresión.

Más código para ayudar a enteder esto, donde se crea un Objeto Booleano con valor false y se asigna a la variable x.

// Crear el Objeto Booleano con valor false
var x = new Boolean(false);
// Comparación abstracta de x con el primitivo Booleano con valor false.
console.info(x == false);  // Devuelve verdadero
// Comparación del valor de la propiedad toString() con el primitivo Booleano con valor false.
console.info(x.toString() == false); // Devuelve false
// Comparación del valor de la propiedad valueOf() con el primitivo 
console.info(x.valueOf() == false); // Devuelve verdadero
// Operador ternario, en caso verdadero devolverá true, en caso contrario, devolverá false
console.info(x ? true: false); // Devuelve verdadero

En cuanto a lo que el estándar dice sobre esto, en 12.14.3 Runtime Semantics: Evaluation, se incluye el algoritmo para evaluar la exprsión, donde uno delos primeros paso es convertir a Booleano, lo cual se describe en 7.1.2 ToBoolean ( argument ), donde se indica lo siguiente:

The abstract operation ToBoolean converts argument to a value of type Boolean according to Table 10:

Table 10: ToBoolean Conversions

Argument Type    Result
Undefined        Return false.
Null             Return false.
Boolean          Return argument.
Number           Return false if argument is +0, -0, or NaN; otherwise return true.
String           Return false if argument is the empty String (its length is zero); 
                 otherwise return true.
Symbol           Return true.
Object           Return true.

Nótese que se indica que cuando el argumento sea de tipo objeto se devuelve true.

Rubén
  • 10,857
  • 6
  • 35
  • 79
0

En dos palabras.

El primitivo booleano solo puede tomar los dos valores 'true' o 'false' pero el Objeto Booleano puede valer Null si no ha sido asignado a un valor previamente.