New Syntax in the add method


#1

Hello,
In the last part of the Bulding a Cash register lesson (You Deserved It!), in the prewritten code for the add method there is a line:
this.total += (itemCost || 0);
I don't fully understand the reason to have (itemCost || 0) rather than simply:
this.total += itemCost;

What are the benefits of placing the boolean operator inside the statement?


#2

It's a way to prevent non-numbers from being added to the total. Try this little function to test it out...

var sumTotal = 0;
function addTo(number){
    return sumTotal += number || 0;
}
addTo(NaN);
console.log(sumTotal);   // 0

Now try these lines,

console.log("sticks" || "stones");  // sticks

console.log(1 || false);            // 1
console.log(false || 1);            // 1

console.log(0 || 0);                // 0

If the first operand is truthy, it is the yielded value of the expression. If it is not truthy, then the second operand, regardless of truthiness is the yielded value.

In our program, because we are performing addition the data type of sumTotal has a bearing on the type that will be accepted (namely, number) so the value NaN for number is falsy, thus yielding to the second operand, 0, which is added with no change or corruption of the accumulated total.


#3

Hello and thanks for your answer,
It's quite interesting how JavaScript treat logical operators with non boolean types.
If I understand correctly:
1) Strings except '0' and 'false' will be equivalent with true
2) numbers except 0 will be equivalent with true

Now then, what is the logic behind the type returned by the operator? Sometime the expression is returning a boolean (true or false) sometime 0 or 1.


#4

Any string that is not the empty string is truthy. This means a length > 0. Regardless what the string is, if it is not empty ('' or "") it evaluates to a true. This is contrary to your observation.

console.log('' || "");   //

We don't see it, but it did log the second empty string even though it was falsy. To further illustrate,

console.log("" || " ");  //

Again we don't see it, but a space character is logged, this time as truthy. The only time '0' is false, is if it is being evaluated as a number, meaning it would have to be converted before evaluating. In its present state, it is a string with length == 1.

Eg.

 > '0' && 0 || 1
=> 1

Since && is evaluated first, '0' is converted to 0 and compared. false && false is false. Consequently the OR operand wins out.

An object is a string any time it is expressed in quotes. That is the only object in JavaScript that is written with quote delimiters. If we look closely we see there are string objects everywhere. When we examine an object literal, { key : value } we discover that the keys are string objects. Iterate over any object and examine the type of the keys. They will all render as 'string'.

var obj = { one: 1, two: 2, three: 3 };
for (var key in obj) {
    console.log(key, typeof key);
}

Output

one string
two string
three string

Back to Boolean expressions, we can see that there is a little more at work here that just a simple true:false scenario. It's demonstrated that we don't always yield a Boolean from an expression, but there is the Boolean aspect of truthiness in play.

'false' is truthy because it is a string with length > 0. false is false because it is a Boolean primitive that needs no evaluation. 0 as a number is falsy, unlike any other number as you correctly objserve.


#5

Hello,
This is probably the better explanation of the subject I ever read. Yes, my observation was wrong indeed.

There is a last thing:
console.log('0' && 1);
returns 1 (number) as the string is truthy, therefore truthy && 1 returns 1 (number)

Now if '0' was converted to number first '0' && 1 would be equivalent to 0 && 1 and should return 0 (number).
Is there a precedence rule on the type conversion?


#6

Here we need to consider how JavaScript parses the expression.

string AND number

'1' && 1           =>  1
typeof ('1' && 1)  => number

number AND string

1 && '1'           => '1'
typeof (1 && '1')  => string

Starting to make sense? It's basically working with the logical expressions directly, as opposed to making them a conditional in an if, for, or while statement.


#7

We can also examine logical expressions in a ternary statement:

function andAB(a, b){
    return [a, b, a && b, a && b ? true : false, typeof (a && b) ]
}

console.log(andAB('1', 1));     //  [ '1', 1, 1, true, 'number' ]
console.log(andAB(1, '1'));     //  [ 1, '1', 1, true, 'string' ]

Paste the function in your console and your can run it on all manner of logical AND expressions with two operands. Similar code can be written for OR, (||) as well as the range of Bitwise operators. This one just became a keeper for me.