Reputation: 2517
Short-circuit evaluation determines if the first value is falsey. If so, return the second value, as follows:
var x = y || z; // if y is falsey return z
Is there a way to disregard zero-values as being falsey when using short-circuit evaluation without resorting to if/else statements or ternary operators?
Upvotes: 12
Views: 2116
Reputation: 95
You could use the bitwise NOT Javascript operator ~
to convert the 0
to -1
(it inverts the bits of the number). As you can imagine it converts -1
back to 0
and that would be the only possible falsey value. Common falsy objects like undefined
, NaN
or ''
would become truey, which might or might not be what you want.
Your code would then look like this:
var x = ~y || z;
Upvotes: 0
Reputation: 386654
You could check first if y
is unequal to zero and take the numerical value and get the result of the default of z
for y
.
x = +(y !== 0) && (y || z)
How it works:
expression y part result result comment ---------------------- --------- ----------- ------ ---------------------------- +(y !== 0) && (y || z) complete expression +(y !== 0) 0 0 0 result found, omit next part because of falsy value +(y !== 0) 1 1 check next part 1 && (y || z) y y take y, omit default +(y !== 0) undefined 1 check next part 1 && (y || z) z z take z as default
function x(y, z) {
return +(y !== 0) && (y || z);
}
console.log(x(0, 42)); // 0
console.log(x(4, 42)); // 4
console.log(x(undefined, 42)); // 42
console.log(x(0, null)); // 0
console.log(x(4, null)); // 4
console.log(x(undefined, null)); // null
console.log(x(0, 0)); // 0
console.log(x(4, 0)); // 4
console.log(x(undefined, 0)); // 0
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3
Reputation: 874
EDIT:
If z
is a number, you can maybe use a trick like this:
var x1 = Number(y===0 && '0' || y || z)
// or
var x2 = (y===0 && '0' || y || z)-0
var z = -1;
var y = 42;
var x = y || z;
var x1 = Number(y===0 && '0' || y || z)
var x2 = (y===0 && '0' || y || z)-0
console.log('x:',x, ' x1:',x1, ' x2:',x2);
var y = 0;
var x = y || z;
var x1 = Number(y===0 && '0' || y || z)
var x2 = (y===0 && '0' || y || z)-0
console.log('x:',x, ' x1:',x1, ' x2:',x2);
var y = null;
var x = y || z;
var x1 = Number(y===0 && '0' || y || z)
var x2 = (y===0 && '0' || y || z)-0
console.log('x:',x, ' x1:',x1, ' x2:',x2);
Original answer:
Maybe simple way can work (3 equivalents)
var x = (y === 0) ? 0 : (y || z);
var x = (!y && y!==0) ? z : y;
var z = 'Was falsey';
var y = 42;
var x = y || z;
var x1 = (y === 0) ? 0 : (y || z);
var x2 = (!y && y!==0) ? z : y;
console.log('x:',x, 'x1:',x1, 'x2:',x2);
var y = 0;
var x = y || z;
var x1 = (y === 0) ? 0 : (y || z);
var x2 = (!y && y!==0) ? z : y;
console.log('x:',x, 'x1:',x1, 'x2:',x2);
var y = null;
var x = y || z;
var x1 = (y === 0) ? 0 : (y || z);
var x2 = (!y && y!==0) ? z : y;
console.log('x:',x, 'x1:',x1, 'x2:',x2);
Upvotes: 1
Reputation: 2454
Edit: this uses a ternary operator, so if that's not what you're looking for, don't use this.
Of course this is another simple way to do it:
var x = y || y==0?0:z;
if
y
is truthy, thenx
is set toy
if
y
is falsy, andy==0
, thenx
is set to0
if
y
is falsy, andy!=0
, thenx
is set toz
;
Upvotes: 1
Reputation: 26171
You may wrap your number into a Number object and check so;
var x = new Number(0) || console.log("never gets printed");
console.log(parseInt(x));
//or
console.log(x.valueOf());
Upvotes: 2