'&&' operator in Javascript vs in Java

1.5k Views Asked by At

I am currently reading JavaScript from JavaScript: The Definitive Guide. On page 76, there is this statement written,

o && o.x // => 1: o is truthy, so return value of o.x

Being a Java programmer I want to ask, why is it returning 1 instead of 'true' In Java this was not the case, but anyway I know JavaScript is different but the Logical AND mechanism is the same everywhere.(In C it returns 1 as true.)

I am asking is, why does it makes sense for this behavior at all?
Is there any way, I can ensure to return only the true or false values?

6

There are 6 best solutions below

0
On BEST ANSWER

As per the Spec for Binary Logical Operators

The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

This is a feature used in javascript a lot, one common use case is to assign a default value to a variable if it is not defined. Like assume you are expecting a options object as a param but is not mandatory so the user may not pass it

function x(options){
    options = options || {};
    //now your can access optionx.a without fearing whether options is undefined
}

You can do something like !!(o && o.x) to always get a true/false

1
On

You can use Boolean(o && o.x); to get true or false

0
On

if we have:

expr1 && expr2

&& Returns 'expr1' if it can be converted to false; otherwise, returns 'expr2'. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.

So if we have:

Var xyz = a && b; //where a is undefined(false) and b is 123, then it will allocate undefined.

In case of if statements, these values are specifically converted to boolean.

Refer the following link: "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators"

0
On

It's returning the value of the right operand. If the value of o.x was true, it would return true. If the value of o.x was 'banana', it would return 'banana'.

var o = {x:true};
console.log(o && o.x);

0
On

Technically && operator implemented to return the first operand if it's value is not zero, and returns the second operand otherwise in a lot of languages including Java, C/C++, Javascript, Perl... While most of the languages accepts any type of operands, Java forces you to use boolean operands so it always returns true or false. In order to force a boolean result in Javascript use:

Boolean(a && b)
1
On

This behaviour is called coercion. Coercion is the action of forcing an object to behave like other type, and the logical operators can produce coercion when trying to access the value of the object to be evaluated.

It is important to remember the table for truthy and falsy values, because due to coercion, different results can be obtained.

  • false produces false
  • 0 produces false
  • “” produces false
  • NaN produces false
  • null produces false
  • undefined produces false

Everything else produces true, including the text "0" and "false", functions, arrays and empty objects.

Given the rules for logic operators, exists short-circuit evaluation in JavaScript, e.g:

0 && 1; //-> 0, falsy value
!(0 && 1); //-> true, falsy value negated
!!(0 && 1); //-> false, boolean falsy value

void 0 && alert("1") //-> undefined (void produces undefined)
[] && Math.ceil(9.1) //-> 10, truthy value
{} && someFunc() //-> the result of someFunc()

0 || null; //-> null, falsy value
null || "0"; //-> "0", truthy value
"" || void 1; //-> undefined, falsy value
!!(+"5px" || {}); //-> true, boolean truthy value

Coercion is useful when you have to validate default values, in order to prevent errors, e.g.

function divide (a, b) {
    a = +a; //-> coerced to number
    b = +b; //-> coerced to number
    if (!a) return 0; //-> NaN or zero
    return b && a / b; //-> b must be a number different from zero
}

divide(); //-> 0
divide(5); //-> NaN, no error thrown!
divide(5, "a"); //-> NaN, no error thrown!
divide(5, 0); //-> 0, division by zero prevented!
divide(49, 6); //-> 8.1666

If you want to prevent returning NaN, just add another coercion in the return statement:

return (b && a / b) || 0;

You can check other coercion cases: JavaScript Coercion


Happy coding!