Object destructuring is a very often used technique these days. It allows to destructure variables from an object, so we don't have to repeat our selves.
An example of preserving object reference:
const orig = {
foo: {
bar: 1
}
}
const { foo } = orig
console.log(foo.bar) // 1
console.log(orig.foo.bar) // 1
foo.bar++
console.log(foo.bar) // 2
console.log(orig.foo.bar) // 2
const response = {
name: 'Name',
last_name:' Last Name'
}
Now we can access properties this way:
console.log(response.name, response.last_name)
But, this is much better, if you need to access these variables multiple times:
const { name, last_name } = response
console.log(name, last_name)
We can rename destructured variables.
const { name: newName, last_name: newLastName } = response
console.log(newName, newLastName)
Conside we have this nested object:
const nestedObj = {
levelOne: {
levelTwo: {
someProperty: 'hello'
}
}
}
No worries, we can destructure even a deep nested properties, it would be cumbersome, though 😄
const { levelOne: { levelTwo: { someProperty } } } = nestedObj
console.log(someProperty) // hello
But what if we try to access undefined properties?
const { levelOne: { testVar: { someProperty } } } = nestedObj
would throw Error: Cannot read properties of undefined (reading 'someProperty'), because testVar
property doesn't exist inside levelOne
property. We can avoid this by using default values:
const { levelOne: { testVar: { someProperty } = {} } } = nestedObj
Here, we assign an empty object to a testVar
, thus it won't throw an error.
Sometimes we have a need to override let variable with a destructured variable.
Destructuring needs to be either after a let, const or var declaration or it needs to be in an expression context to distinguish it from a block statement
let emptyVar = null
const obj = {
dunno: 'someValue'
}
;({ dunno: emptyVar } = obj)
Here we reassigning emptyVar
with the value dunno
from the obj
by wrapping in parentheses (it's called expression).