sookie
sookie

Reputation: 2517

Allow for zero-value in short-circuit evaluation

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

Answers (5)

mik13ST
mik13ST

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;
  • ~(-2) equals 1
  • ~(-1) equals 0
  • ~(-0) equals -1
  • ~(0) equals -1
  • ~(1) equals -2

Upvotes: 0

Nina Scholz
Nina Scholz

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

NatNgs
NatNgs

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

clabe45
clabe45

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, then x is set to y

if y is falsy, and y==0, then x is set to 0

if y is falsy, and y!=0, then x is set to z;

Upvotes: 1

Redu
Redu

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

Related Questions