To get more clarity on how nullish coalescing (??
) works, it would be wiser to compare it with the OR operator (||
) and understand.
Before we head towards the blog's main topic, I want to brief you about Falsy values in javascript.
Falsy & Truthy values in Javascript:
In this topic we will talk about:
Primitive Data Types
Falsy values
Truthy values
Primitive Data Types:
Primitive data types are a set of basic data types in javascript.
There are seven primitive datatypes in javascript:
Null
Number
String
Symbol
Boolean
BigInt
Undefined
const a = null;
console.log(typeof(a)); // Output: object
const b = 12;
console.log(typeof(b)); // Output: number
const c = "abhay";
console.log(typeof(c)); // Output: string
const d = Symbol("Hello");
console.log(typeof(d)); // Output: symbol
const e = true;
console.log(typeof(e)); // Output: boolean
const f = BigInt(123456767544);
console.log(typeof(f)); // Output: bigint
const g = undefined;
console.log(typeof(g)); // Output: undefined
We will discuss them slowly as we go through the blog until then you should know that there are seven primitive data types whereas an object
is a non-primitive datatype in javascript. Talking about an array
is also a non-primitive data type.
const array = [1,2,3,4,5,6];
console.log(typeof(array)); //Output: object
Falsy values:
A falsy value in javascript is a value that is considered to be false
in boolean context.
So basically in javascript, booleans are the primitive data types that can either be true
or false
depending on the result of evaluating an expression or condition.
console.log(3>0);
//Output: true
console.log(3<0);
//Output: false
As we can see in the above example we have boolean values (true
and false
) under the respective conditions.
Javascript has characterized a set of values that are considered to be false
.
These are the falsy values in javascript:
Value | Description |
false | The keyword false |
0 ,-0 | The number 0(positive and negative both) |
"" , '' , `` | Empty string |
null | absence of any value |
undefined | absence of the value until we assign it some value |
NaN | not a number (illegal numbers) |
From the above-mentioned falsy values I would like to talk about the following values:
Undefined:
When we declare a variable and forget to assign it some value, it will always be undefined
until we initialize/assign it with some value, which can be a string, number, object, array, etc.
let x; //Declared x but not assigned some value to it
console.log(x); //Output: undefined, as x has no value been assigned or x has not been initialized yet
Here we declared variable x
but did not assign it some value so when we try to access variable x
it will show undefined
in the output.
But if in the future we assign it with some value, it will not show undefined
.
//in continuation with the above example
x = "abhay"; //we initialized x that we declared in the previous code snippet
console.log(x); // Output: abhay
Null:
Suppose we are trying to access some value (for example we are trying to access productCode) from a server but the value (productCode) does not exist in the server database, so in this case it will show us null
as there does not exist any value (productCode) in the server.
Null vs Undefined:
let y; // y is declared but not assigned any value so in this case javascript automatically sets undefined until it is assigned some value by the user
let x = null; // but in the case of null the user has to manually set the value of the variable to null.
console.log(y); // Output: undefined
console.log(typeof(y)); // Output: undefined
console.log(x); // Output: Null
console.log(typeof(x)); // Output: Object
console.log(x == y); // Output: true, takes only values into consideration
console.log(x === y); // Output: false, takes values as well as there data type into consideration
Loose equality operator(==) returns true because it assumes that both x
and y
do not have any value. But in the case of strict equality operator(===), it takes their data types also into consideration which is different for undefined
and null
hence it returns false
.
We will talk more about null
and undefined
after NaN
(not a number).
NaN (not a number):
console.log(typeof(NaN)); // Output: number
console.log(2 * "haule"); // Output: NaN
As we can see in the above example, we are trying to multiply a number( 2
in this case ) with a string ("haule"
). So in this case, we would not get a number and hence it returns NaN
(Not a Number).
We can classify numbers as legal numbers and illegal numbers. In the above example, "haule"
(a string) will be treated as an illegal number whereas 2
is a legal number.
let a = "50"; // datatype is string in this case as we have wrapped number inside double inverted comma
let b = 10; // it is a number
let c = "haule"; // again a string
console.log(a/b); // a/b = "50"/10 Output: 5
console.log(a/c); // a/c = "50"/"haule" Output: NaN
If there's only a number inside a string data type as shown above let a = "50"
then it will be considered as a legal number and it will be converted to a number by javascript internally through toNumber()
(it is an in-built function in javascript) function.
In the first console.log(a/b)
the value of a
("50"
is a legal number) will be converted to a number through toNumber()
function internally by javascript and finally, the operation will look like 50/10
hence the result is 5
.
In the second console.log(a/c)
the value of c
("haule"
is an illegal number) cannot be converted into a number and when we perform any operation with an illegal number it will return NaN
(not a number).
let length = 10;
let breadth; // undefined as we have not assigned it some value
let area = length * breadth; // area = 10 * undefined
console.log(area); // Output: NaN
In the above example when we try to multiply a number with undefined
(10 * undefined)
, javascript internally uses a function toNumber()
and converts undefined
to NaN
and when we multiply NaN
with a number it will result in NaN
.
let length2 = 20;
let breadth2 = null; // we have manually assigned null value to the variable
let area = length2 * breadth2; // area = 20 * null
console.log(area); // Output: 0
In the above example, toNumber()
converts Null
to 0
so when we calculate area
(20 * 0)
we get 0
as the output.
Undefined:
This means the variable has been declared
but its value has not been assigned.returns
NaN
on performing an arithmetic
operation.undefined
value has anundefined
data type
Null:
This means an empty value, the value
does not exist.converts to
0
then operate.The data type of value
null
is anobject
.
Truthy value:
Truthy values are considered true
in the boolean context, anything other than falsy is considered a truthy value. For instance string
, number
, true
(boolean value) etc.
OR operator (||) :
Compares two conditions and returns true
or false
based on the result of each condition.
const a = 3;
const b = -2;
console.log(a>0 || b>0); // 3>0 is true whereas -2>0 is false Output: true
In OR if one of the conditions is true
as in the above case then it will return true
.
const a = -3;
const b = 2;
console.log(a>0 || b>0); // -3>0 is false and 2>0 is true Output: true
Similarly in the above case, one condition was true
that's why it returns true
.
const a = -3;
const b = -2;
console.log(a>0 || b>0); // -3>0 is false and -2>0 is also false Output: false
In the above example, neither of the two conditions was true
so the output is false
.
const a = 3;
const b = 2;
console.log(a>0 || b>0); // 3>0 is true and 2>0 is true Output: true
Here both conditions are true
so the output is true
.
const a = 1; // number data type hence truthy value
const b = 0; // 0 is considered as falsy value
console.log(a || b); //Output: 1
Here, 1
is a truthy value (true
in boolean context) and 0
is a falsy value (false
in boolean context), so it returns true
(1
is considered to be true
as it is a truthy value).
const a = "abhay"; // string
const b = false; // false which is a value of boolean data type
console.log(a || b); // Output: abhay
Here, string ("abhay")
is a truthy value (true
in boolean context) and boolean (false
) is a falsy value (false
in boolean context), hence it returns a string (abhay
).
const a = 123; // number
const b; // will be assigned undefined value as there is no initialization
console.log(a || b); // Output: 123
Here, number (123
) is a truthy value (true
in a boolean context) and variable b
will be assigned an undefined
value which is considered to be a falsy value, hence the output will be 123
(as it is considered to be true
in boolean context).
Nullish coalescing (??) :
Let's see its syntax first:
let val = "abhay"; // string
const example = val ?? 10; // 10 is the default value
console.log(example); // output: abhay
nullish coalescing (??
) operator checks whether the value (val
in the above case) is undefined
or null
, and returns the default value if the value (val
) is undefined
or null
. But in the above code, val
is a string
so it will return (abhay
) only.
Note that nullish coalescing operator (??
) considers null
and undefined
only as falsy values.
//In case of val is undefined
let val; // only declaration so it will be undefined until assigned value
const example = val ?? 10; // 10 is the default value
console.log(example); // output: 10
//In case of val is null
let val = null; // here we are manually assigning null value to the variable
const example = val ?? 10; // 10 is the default value
console.log(example); // output: 10
OR operator (||) vs nullish coalescing (??) :
let valueOne = 0;
let myNumber = valueOne || 10;
let myNumber2 = valueOne ?? 10;
console.log(myNumber); // Output: 10
console.log(myNumber2); // Output: 0
Why is the output different for both the console in above code?
We earlier talked about falsy values, now is the time to apply its concept here.
OR operator considers all falsy values to be false
in boolean context, that's why while comparing 0
with 10
in myNumber
we know that 0
is a falsy value whereas 10
is a number and it is a truthy value so it returns 10
as it is the truthy value (true
in boolean context).
While in the case of the second console.log(myNumber2)
, we are accessing myNumber2
which has the same values being compared (0
and 10
) but with nullish coalescing operator. Nullish coalescing only considers null
and undefined
as falsy values which will be considered as false
in boolean context. That's why it prints 0
as it is not a falsy value as per nullish coalescing operator.
let valueOne = false;
let myNumber1 = valueOne || "haule"; // false is a falsy value for OR operator
let myNumber2 = valueOne ?? "haule"; // false is not considered to be falsy value in case of nullish coalescing operator
console.log(myNumber1); // Output: haule
console.log(myNumber2); // Output: false
Summary:
Primitive data type (nnbbssu) :
null
,number
,boolean
,bigInt
,string
,symbol
,undefined
.Falsy values:
0
,undefined
,null
,false
,""
(empty string),NaN
.
Considered asfalse
in boolean context.
Note: empty array ([]
) or empty object ({}
) is not a falsy value only an empty string (""
) is considered as a falsy value.Truthy values: All values except falsy values.Considered as
true
in boolean context.OR operator: returns
true
if any of the two values being compared istrue
or both of them aretrue
. All falsy values are consideredfalse
in a boolean context.nullish coalescing:
null
andundefined
falsy values are only considered asfalse
values in a boolean context. If thenull
andundefined
value is present it returns the default value.