Falsy
Javascript threats all these values as false.
if (false)
if (null)
if (undefined)
if (0)
if (-0)
if (0n)
if (NaN)
if ("")const data = {
product: "Free candy",
price: 0,
}
// Would not show price 0 kr at all because of falsy!
if (data.price) <Cost>data.price</Cost>
// Output 0 kr. Note that nullcheck loosely compared also detect undefined.
// Below is the same as !x == null || !x == undefined
if (!data.price == null) <Cost>data.price</Cost>Truthy
Javascript threats all these values as true.
if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)Checks and cause gards
Common pattern to check for empty value before making any operations on a variable like toUppercase().
if (value) {
// Run if truthy.
// Check before making operations that would crash runing values like undefined.
// Be aware that truthy values like empty arrays and objects are concidered true {} []
}
if (!value) {
// Run if falsy (for cause gards etc with early exit - one line return
// Be aware that falsy values "", 0 etc is concidered false.
}Null checks
The null (or undefined) value is not loosely equal to any of the other falsy values except undefined and null itself.
if (price == null) console.log("Price is either null or undefined (nullish)")
if (price == undefined) console.log("Price is either null or undefined (nullish)")The value of data is: null
data == 0 false
data == on false
data == data true
data == undefined true
data == false false
data == NaN false
data == "" falseNot dealing with null
Try to avoid returning null in favor of:
- returning a default object instead of null
- throwing an error instead of returning null
Conditional (ternary) operator
Ternary means threesome and takes three operands. This operator is frequently used as a shortcut for the if statement.
Compare truthy and falsly values.
$price ? `${price} kr` : "Free"
$active ? "active-class" : ""Short-circuit evaluation
- Logical expressions are evaluated left to right.
- This compares with truthy and falsely
price && <Amount>{price}</Amount>
// The same as:
if (price) bli blo bla
arr.length && doSomething(arr)
// The same as:
if (arr.length) doSomething(arr)And the or sign checks for falsy
name || <Form>Please enter your missing name</Form>
// The same as:
if (!name) <Form> ...
const name = res.name || "No name found"
// The same as:
if (!res.name) name = "No name found"Nullish coalescing operator (??)
The new Nullish coalescing operator (??) works like ||, but it only returns the
second expression, when the first one is "nullish", i.e. null or undefined.
It is thus the better alternative to provide defaults, when values like "" or 0
are valid values for the first expression, too.
price ?? console.log("Price")<Amount<Form>Please enter your missing name</Form>
// The same as:
if (!name) <Form> ...
const name = res.name || "No name found"
// The same as:
if (!res.name) name = "No name found"Optional chaining (?.)
The optional chaining operator (?.) enables you to read the value of a property
located deep within a chain of connected objects without having to check that each
reference in the chain is valid.
The ?. operator is like the . chaining operator, except that instead of causing an
error if a reference is <Mark>nullish</Mark> (null or undefined), the expression
short-circuits with a <Mark>return</Mark> value of undefined. When used with
function calls, it <Mark>returns</Mark> undefined if the given function does not exist.
const adventurer = {
name: "Alice",
cat: {
name: "Dinah",
},
}
const dogName = adventurer.dog?.name
console.log(dogName)
// expected output: undefined
// Note: The above is the same as: adventure.dog && adventure.dog.name
console.log(adventurer.someNonExistentMethod?.())
// expected output: undefinedDealing with optional callbacks or event handlers
If you use callbacks or fetch methods from an object with a destructuring
assignment, you may have non-existent values that you cannot call as functions
unless you have tested their existence. Using ?., you can avoid this extra test:
catch (err) {
if (onError) { // Testing if onError really exists
onError(err.message);
}
}
// Width optional chaining:
catch (err) {
onError?.(err.message); // no exception if onError is undefined
}Combining with the nullish coalescing operator
The nullish coalescing operator may be used after optional chaining in order to build a default value when none was found:
let customer = {
name: "Carl",
details: { age: 82 },
}
const customerCity = customer?.city ?? "Unknown city"
console.log(customerCity) // Unknown cityCheck arrays
A good way to check an array is empty or not is with length. As long as an array has any elements it concidered a length - even if the value itself is undefined.
Remember that an empty array [] is truthy.
const arr = [undefined]
console.log(arr.length) // 1 (truthy)Check for empty object
An object has no length property. Instead count the key. IE9 and above.
const obj = { name: "Foo" }
if (Object.keys(obj).length) console.log("I have at least one property")If we stringify the object and the result is simply an opening and closing bracket, we know the object is empty.
function isEmptyObject(obj) {
return JSON.stringify(obj) === "{}"
}Using Underscore and Lodash
_.isEmpty(obj)Default arguments neither nullish or falsy
Missing arguments are only replaced with default values in the case of <Mark>undefined.</Mark>
const validate = (toValidate = "MJAU") => {
// Sets toValidate parameter to MJAU ONLY in the argument is undefined.
console.log("tovalidate: ", toValidate)
}