Is it ok to use javascript `??` operator as shorthand - javascript

I normally use ternary operators like:
let foo = str.match(/[*]/g) ? str.match(/[*]/g) : "none!";
Since using PHP, I've noticed the language has a lot of shorthand and for ternary operators, would use:
$foo = $view->test ?? "none";
I have not seen that in javascript (or documentation on it) but tried it like:
let str = "1234";
let foo1 = str.match(/[*]/g) ?? "none;
console.log(foo) // "none"
let str1 = "1*2*";
let foo1 = str1.match(/[*]/g) ?? "none;
console.log(foo1) // ['*','*']
and it seemingly works. Is this an acceptable way of using ternary operators when checking against the existence of an element?

I guess it's totally legit to use the nullish coalescing operator or ??.
See https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator for examples and some documentation on it.
Make sure to check browser compatibility though !
=======
There is also the logical OR || operator which can be used for similiar operations:
o1 = true || true // t || t returns true
o2 = false || true // f || t returns true
o3 = true || false // t || f returns true
o4 = false || (3 == 4) // f || f returns false
o5 = 'Cat' || 'Dog' // t || t returns "Cat"
o6 = false || 'Cat' // f || t returns "Cat"
o7 = 'Cat' || false // t || f returns "Cat"
o8 = '' || false // f || f returns false
o9 = false || '' // f || f returns ""
o10 = false || varObject // f || object returns varObject
Check out : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators for reference

Related

How can I simplify `(variableA && !variableB) || !variableA` expression in JavaScript?

Please see this minimum example:
const result = (variableA && !variableB) || !variableA;
In this expression, I can't simply write this
const result = variableA && !variableB;
Because if variableA = 0, the result will be different
const variableA = 0;
const variableB = undefined;
console.log((variableA && !variableB) || !variableA); // true
console.log(variableA && !variableB); // 0
Is there any way I can simplify this expression?
(variableA && !variableB) || !variableA; if we use factoring to this result below
(!variableA || variableA) && (!variableA ||!variableB)
first part is always true then only second part is enough for u
!variableA ||!variableB
const variableA = 0;
const variableB = undefined;
console.log((variableA && !variableB) || !variableA); // true
console.log(!variableA ||!variableB);
You could use
!(a && b)
or the equivalent with De Morgan's laws
!a || !b
const
f = (a, b) => (a && !b) || !a,
g = (a, b) => !(a && b),
h = (a, b) => !a || !b
console.log(0, 0, f(0, 0), g(0, 0), h(0, 0));
console.log(0, 1, f(0, 1), g(0, 1), h(0, 1));
console.log(1, 0, f(1, 0), g(1, 0), h(1, 0));
console.log(1, 1, f(1, 1), g(1, 1), h(1, 1));
Your answer #nina-scholz is not (explicit) aware of the javascript type-casting. Your own acepted answer will only work in your special usecase while using the ! (not) operator.
const variableA = 0;
const variableB = undefined;
console.log(variableA && variableB); // 0
console.log(variableA || variableB); // undefind
This will neither have a boolean result because even using the boolean operators && and || the resulting type is not boolean.
You need to typecast the variables to boolean before logical operation.
The ! (not) operator will do this explicit. If you double it !! you have surely a boolean value to logical compare. This works also for undefined values.
const variableA = 0;
const variableB = undefined;
console.log(!!variableA && !!variableB); // false
console.log(!!variableA || !!variableB); // false
Now your result of the logical operation is always from a logical boolean expression.
Check your question again:
const variableA = 0;
const variableB = undefined;
console.log("no booleans -----");
console.log(variableA); // => 0 - what is NOT a boolean
console.log(variableB); // => undefined - what is NOT a boolean
console.log("explicit booleans with not operator -----");
console.log(!variableA); // => true - now it is a boolean
console.log(!variableB); // => true - now it is a boolean
console.log("explicit booleans with double not operator -----");
console.log(!!variableA); // => false - now it is a boolean
console.log(!!variableB); // => false - now it is a boolean
console.log("with and without typecast -----");
console.log(variableA && !variableB); // => 0 - what is NOT a boolean
console.log(!!variableA && !variableB); // => false - now all are boolean
console.log("your question with and without explicit typecast -----");
console.log(0 || !variableA); // => true
console.log(false || !variableA); // => true
console.log(0 || true); // => true
console.log(false || true); // => true
As #pc-coder has already shown, you may change your current expression
const variableA = 0;
const variableB = undefined;
console.log((variableA && !variableB) || !variableA);
// expand expression
console.log((variableA || !variableA) && (!variableB || !variableA));
// reduce expression while first part (variableA || !variableA) is always true
console.log(!variableB || !variableA);
// the above will work thru automatic typecast with not operator
// or exclude the not operator and typecast explicit
console.log(!(!!variableB && !!variableA));

You Don't Know JS: Up & Going - example problem

In page 38 I found - arrays are by default coerced to strings by simply
joining all the values with commas (,) in between. You might think
that two arrays with the same contents would be == equal, but
they’re not:
var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
a == c; // true
b == c; // true
a == b; // false
But when I run my code like the following:
var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
console.log(typeof a == c); // false
console.log(typeof b == c); // false
console.log(typeof a == b); // false
I got different answers! Why typeof a == c and typeof b == c is false here?
its doing
typeof a == c
=> (typeof a) == c
=> "object" == c // which is false
basically typeof operator works before == sign
My cliche advice, always use paranthesis to make your intent clear
typeof (a==b) vs (typeof a) == b
The typeof operator returns the type of the content of a variable as a string. So if your variable a contains an array, typeof a will return the string "object" (as arrays are a special kind of objects).
So typeof a == c and typeof b == c compare the string "object" with the string "1,2,3". As they are obviously not the same, this returns false.
Note that the typeof operator has a higher precedence than the == operator.

Why || operator is behaving like this?

Why _value is foo on second function call? It took me a while to find this bug.
function doSomething(value) {
console.log('should be:', value);
const _value = value || Math.random() > 0.5 ? 'foo' : 'bar';
console.log('actually is:', _value);
}
let values = ['foo', 'bar'];
const first = doSomething(values[0]);
const second = doSomething(values[1]);
To understand better I put a parenthes around the testing code:
(value || Math.random() > 0.5)
Since value is always defined (non null) the condition avaluates to true and assigns 'foo' to '_value'
Hope this explains it for you.
Because the expression
const _value = value || Math.random() > 0.5 ? 'foo' : 'bar';
is evaluated as:
const _value = (value || (Math.random() > 0.5)) ? 'foo' : 'bar';
The conditional operator has lower precedence than other operators in the expression.
value is a non-empty string, so it evaluates to true in boolean context. Thus, the condition evaluates to true, and the final result is always 'foo'.
Because:
> 'bar' == true
false
So:
const _value = value || Math.random() > 0.5 ? 'foo' : 'bar';
_value will be randomly assigned the value 'foo' or 'bar', because value is 'bar' which evaluates to false, so the second half of the or-expression || is evaluated and assigned to _value.
Try this.
const _value = value || (Math.random() > 0.5 ? 'foo' : 'bar');
Because JS in your code check such
`if(value || Math.random() > 0.5){
_value = 'foo';
}else{
_value ='bar'
}`
The construct const a = b || c is common Javascript shorthand. It means:
If b is not falsy assign it to a. Otherwise assign c to a.
It can also be written const a = b ? b : c; or
const a;
if (b) a = b;
else a = c;
A value is falsy generally speaking if it is empty or has the value zero.

That Operator || in console.log() works like || operator?

How it's work for example;
let x;
console.log(x || 2); // 2
if
let x = 4;
console.log(x || 2); // 4
if
let x = 5;
let y = 7;
console.log( y || x || 2);
it's mean that console.log() write first value that is true ?
What you're seeing isn't related to console.log. It's called short circuiting.
When comparing values with ||, it will always return the first truthy value. If no truthy values are present, it will return the last value being compared.
let a = false || true;
let b = false || null || 'b';
let c = undefined || !a || 10;
let d = undefined || false || null; // no truthy values
console.log(a); // true
console.log(b); // 'b'
console.log(c); // 10
console.log(d); // null
let x = 5;
let y = 7;
console.log( y || x || 2); //return 7
expr1 || expr2 Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true.
Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

What does || mean in JavaScript? [duplicate]

This question already has answers here:
Javascript || operator
(5 answers)
Closed 9 years ago.
I'm fairly new to JavaScript. What does || do?
It is a condition operator, meaning “or”, typically used like this:
if (browserIsMSIE || browserIsFirefox) {
…
}
MDN Expressions and Logical statements
(Logical OR) Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true; if both are false, returns false.
var o1 = true || true; // t || t returns true
var o2 = false || true; // f || t returns true
var o3 = true || false; // t || f returns true
var o4 = false || (3 == 4); // f || f returns false
var o5 = "Cat" || "Dog"; // t || t returns Cat
var o6 = false || "Cat"; // f || t returns Cat
var o7 = "Cat" || false; // t || f returns Cat
It's same as in other C type languages. A Logical Operator, for the OR condition.
Here's the Docs on Mozilla Developer Network.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
If something1 or something2, do something: equates to this
if (something1 || something2){
... do something
}
If something1 and something2, do something: equates to this
if (something1 && something2){
... do something
}

Categories

Resources