Last active
November 12, 2019 08:14
-
-
Save joeytwiddle/76d94d4cd45d247803286d73dd8a7b83 to your computer and use it in GitHub Desktop.
Getting properties from an object which might be null
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A common situation in Javascript: | |
// | |
// We have a variable `obj`, and we want to get `obj.foo.bar` | |
// | |
// But `obj` might be null or undefined, or `obj.foo` might be null or undefined | |
// | |
// So how can we try to get `obj.foo.bar` without risking an error? | |
// Here are a few different ways to do that. Which one is clearest? | |
// Note that the first way becomes longer if obj and foo have longer names, due to repetition | |
const result = obj && obj.foo && obj.foo.bar; | |
const result = ((obj || {}).foo || {}).bar; | |
const result = optional(optional(obj).foo).bar; | |
// where | |
function optional(obj) { | |
return obj == null ? {} : obj; | |
} | |
// Note that `obj == null` is a shortcut for `(obj === undefined || obj === null)` | |
// and is the only time `==` should ever be used! | |
// Instead of using the `optional()` function, you could use a similar function from | |
// one of these popular libraries: | |
// https://github.com/tc39/proposal-optional-chaining/issues/69#issuecomment-409045384 | |
// We could have implemented `optional()` like this: `return obj || {};` | |
// That would match exactly the second inline method above. | |
// But the provided implementation is preferable because it allows falsey | |
// but non-empty values like 0 and false and '' to pass through | |
// In normal circumstances, if `obj.foo` is falsey, then: | |
// | |
// - The first method will return the falsey `obj.foo`, e.g. `0` or `false` | |
// - The second method will return `undefined` | |
// - The third method will return `undefined` | |
// | |
// If you are about to check `result` for truthiness, then it doesn't matter | |
// which method you use. | |
// Coffeescript and TypeScript (since 3.7) have the existential operator: | |
result = obj?.foo?.bar | |
const result = obj?.foo?.bar; | |
// And this has been proposed for Javascript too: https://github.com/tc39/proposal-optional-chaining |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment