2020 Solution, ?.
and ??
You can now directly use ?.
(Optional Chaining) inline to safely test for existence. All modern browsers support it.
??
(Nullish Coalescing) can be used to set a default value if undefined or null.
aThing = possiblyNull ?? aThing
aThing = a?.b?.c ?? possiblyNullFallback ?? aThing
If a property exists, ?.
proceeds to the next check, or returns the valid value. Any failure will immediately short-circuit and return undefined
.
const example = {a: ["first", {b:3}, false]}
example?.a // ["first", {b:3}, false]
example?.b // undefined
example?.a?.[0] // "first"
example?.a?.[1]?.a // undefined
example?.a?.[1]?.b // 3
domElement?.parentElement?.children?.[3]?.nextElementSibling
null?.() // undefined
validFunction?.() // result
(() => {return 1})?.() // 1
To ensure a default defined value, you can use ??
. If you require the first truthy value, you can use ||
.
example?.c ?? "c" // "c"
example?.c || "c" // "c"
example?.a?.[2] ?? 2 // false
example?.a?.[2] || 2 // 2
If you do not check a case, the left-side property must exist. If not, it will throw an exception.
example?.First // undefined
example?.First.Second // Uncaught TypeError: Cannot read property 'Second' of undefined
?.
Browser Support - 92%, Nov 2021
??
Browser Support - 92%
Mozilla Documentation
--
Logical nullish assignment, 2020+ solution
New operators are currently being added to the browsers, ??=
, ||=
and &&=
. They don't do quite what you are looking for, but could lead to same result depending on the aim of your code.
NOTE: These are not common in public browser versions yet, but Babel should transpile well. Will update as availability changes.
??=
checks if left side is undefined or null, short-circuiting if already defined. If not, the left side is assigned the right-side value. ||=
and &&=
are similar, but based on the ||
and &&
operators.
Basic Examples
let a // undefined
let b = null
let c = false
a ??= true // true
b ??= true // true
c ??= true // false
Object/Array Examples
let x = ["foo"]
let y = { foo: "fizz" }
x[0] ??= "bar" // "foo"
x[1] ??= "bar" // "bar"
y.foo ??= "buzz" // "fizz"
y.bar ??= "buzz" // "buzz"
x // Array [ "foo", "bar" ]
y // Object { foo: "fizz", bar: "buzz" }
Browser Support Nov 2021 - 90%
Mozilla Documentation