What purpose do &&=, ||= and ??= serve? - javascript

I have seen this syntax in node.jsv15.0.1: &&=, ||= and ??=.
But I don't know what it does. Does anyone know?

These are the new logical assignment operators. They're similar to the more familiar operators like *=, +=, etc.
someVar &&= someExpression is roughly equivalent to someVar = someVar && someExpression.
someVar ||= someExpression is roughly equivalent to someVar = someVar || someExpression.
someVar ??= someExpression is roughly equivalent to someVar = someVar ?? someExpression.
I say "roughly" because there's one difference - if the expression on the right-hand side isn't used, possible setters are not invoked. So it's a bit closer to:
someVar &&= someExpression is like
if (!someVar) {
someVar = someExpression;
}
and so on. (The fact that a setter isn't invoked is unlikely to have an effect on the script, but it's not impossible.) This is unlike the other traditional shorthand assignment operators which do unconditionally assign to the variable or property (and thus invoke setters). Here's a snippet to demonstrate:
const obj = {
_prop: 1,
set prop(newVal) {
this._prop = newVal;
},
get prop() {
return this._prop;
}
};
// Setter does not get invoked:
obj.prop ||= 5;
??, if you aren't familiar with it, is the nullish coalescing operator. It will evaluate to the right-hand side if the left-hand side is either null or undefined.

Those are called Logical Assignment Operators and there are three in total:
Logical AND assignment (&&=)
Logical OR assignment (||=)
Logical nullish assignment (??=)
Fundamentally they all do the same: The logical operators &&, ?? and || in front of the = as in x logical-operator= y can be rewritten as x logical-operator (x = y). Their only purpose is to replace more verbose code:
x &&= y does nothing if x is not truthy and changes x's value to y if x is truthy. It is the same as:
if (x) {
x = y
}
x ||= y does nothing if x is truthy and changes x's value to y if x is not truthy. It is the same as:
if (!x) {
x = y
}
x ??= y does nothing if x is not nullish and changes x's value to y if x is nullish. It is the same as:
if (x === null || x === undefined) {
x = y
}
Here are some examples to further your understanding of these:
const y = 'other value'
let def = 'initial' // truthy value
let zero = 0 // not truth value
let undef = undefined // nullish value
def &&= y // def = 'other value'
zero &&= y // zero = 0
undef &&= y // undef = 'undefined'
def ||= y // def = 'initial'
zero ||= y // zero = 'other value'
undef ||= y // undef = 'other value'
def ??= y // def = 'initial'
zero ??= y // zero = 0
undef ??= y // undef = 'other value'

a = a || b is equivalent to a ||= b => if a is true, a return but if a is false b return.
a = a && b is equivalent to a &&= b => if a is true, b return but if a is false a return.
a = a ?? b is equivalent to a ??= b => if a just is null or undefined, b return but if a is true a return.
note: null, undefined, "", 0, NaN are false
examples:
let a = -22
const b = false
a &&= b
console.log(a) // false
let a = 0
const b = 'hello'
a ||= b
console.log(a) // hello
let a = false
let b = true
a ??= b
console.log(a) // false
let a = null
let b = true
a ??= b
console.log(a) // true
If you do not understand, read it again!

Related

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

Can someone explain what this JS snippet is doing?

Can someone please tell me what this snippet is doing?
Is it setting x to true if y is undefined?
var x = false;
var y = x === true;
The code
var x = false;
var y = x === true;
console.log(y);
is simply checking the condition x === true, like other programming language it will result to either true or false. Since you have var x = false; the condition x === true will result in false as false === true is always false. Now, the result of this condition is being assigned to the new variable y as var y = x === true; so the value for y will be false.
Set x to false
Is x exactly-equal to true?
2.1. If so, then set y to true
2.2. Otherwise, set y to false
There is no invokation of of global.undefined in this fragment.
The first line should be pretty clear, it sets x to false. The second line is a bit more difficult, first, it compares x to true. If x is exactly equal to true, it will set y to true. Since x is false, the comparison will also return false, so y will be set to false.
TL;DR, this is a convoluted way of setting y to false.
=== is a strict comparison operator. The value of variable y will only true if x is boolean and true, y will be false otherwise. Check this snippet out for example:
let a = 1;
console.log(a == true); // print true
let b = 1;
console.log(b === true); // print false, because `b` is a number, not boolean
let c = true;
console.log(c == true); // print true
let d = true;
console.log(d === true); // print true, because `d` is a boolean and its value is `true`
This var y = x === true; statement means: keep the returned value of (x === true) in the y variable. In your case, y will hold false as its value since x is a boolean, but its value is false.
Strict Equality Operator, === has a greater precedence over Assignment Operator, =. Therefore the check for x is done before assigning its value to y.
You can break this down into three statements.
var x = false
var tmp = (x === true)
var y = tmp
Since x is false, y will also get set to false.

When does a !== a? [duplicate]

Is there any value for what x === x returns false without NaN?
For example:
> x = 1
1
> x === x
true
> x = {}
{}
> x === x
true
> x = new Date()
Wed Nov 13 2013 15:44:22 GMT+0200 (EET)
> x === x
true
> x = NaN
NaN
> x === x
false
I see that the only value where x === x returns false is when isNaN(x) === true.
Is there another value of x for what x === x returns false? An official reference would be welcome!
The strict comparison between two equal non-NaN values will always be true (SLaks's answer correctly quotes the spec). However, it's possible for the expression x to change its value during the evaluation of the the equality. This can happen with property access when using accessor property descriptors (i.e., property getters):
foo = {};
Object.defineProperty(foo, "bar", {
get: function() {
return Math.random();
}
})
foo.bar === foo.bar; // false
If you do this for the global object window (or global in Node), then you can see the x === x comparison fail for a global-scope variable:
Object.defineProperty(window, "bar", {
get: function() {
return Math.random();
}
})
bar === bar; // false
The spec lists the exact rules for strict equality.
There are no other such cases, unless you count +0 and -0.
The SameValue algorithm (used for validating changes to read-only defined properties) has no such exceptions.

&& operator on strings in javascript

I have the following expression :
if(a && b === c) {//do something}
What would be the meaning of this condition if I consider that a,b, and c are strings ?
This is equal to if (a == true && b === c). (note that == is lose comparison. Eg. "foo" is loosely equal to true, however "" is not loosely equal to true, hence this says "if a is not an empty string, and b has the same content, and is the same type as c, then do something")).
Examples:
var a = 'foo';
var b = 'bar';
var c = 'bar';
Will be true because a is not falsy (a non empty string is truthy), and b is the same type and has the same content as c.
var a = '';
var b = 'bar';
var c = 'bar';
Will be false because a is falsy (an empty string is falsy).
var a = 'foo';
var b = 'rab';
var c = 'bar';
Will be false because b does not have the same content as c.
var a = 'foo';
var b = true;
var c = 1;
Will be false because b is not the same type as c (boolean vs number - with == this would be true, as true == 1).
Your expression expands to this:
if (a) {
if (b === c) {
// do something
}
}
It first checks that a is some truthy value. It then checks that b and c are of the same value and the same type. Read up on truthy and falsey values in JavaScript.
This means:
a is truthy
AND
b exactly equal to c (including type)
Here a is truthy means it is NOT ('undefined' or "" or 'null' or 0 or 'NaN' or 'FALSE')
if a have some value (not null and "") and b's value (string, case sensitive) is equal to c's value then your code

Categories

Resources