I came across this destructuring expression in an article.
const words = ['oops', 'gasp', 'shout', 'sun'];
let { length } = words;
console.log(length); // 4
How does length
get the value of 4? I know .length
is a property of the array, but how does this syntax work? It seems to be doing let length = words.length;
and in fact in babel does output it as such. But my question is what is the logic behind it?
What is confusing me is the mix of an array of values and the the use of {length}
.
I have read MDN 's description but can't see this example explained.
The length property of an array is an unsigned, 32-bit integer that is always numerically greater than the highest index of the array. The length returns the number of elements that a dense array has. For the spare array, the length doesn't reflect the number of actual elements in the array.
Destructuring in JavaScript is a simplified method of extracting multiple properties from an array by taking the structure and deconstructing it down into its own constituent parts through assignments by using a syntax that looks similar to array literals.
To destructure an array in JavaScript, we use the square brackets [] to store the variable name which will be assigned to the name of the array storing the element. const [var1, var2, ...]
Destructuring is a JavaScript expression that allows us to extract data from arrays, objects, and maps and set them into new, distinct variables. Destructuring allows us to extract multiple properties, or items, from an array at a time.
I had the same question so I read the docs and it finally clicked for me that the variable (length
) is just being assigned the Object’s value at the key with the same name as the variable (words[length]
).
That may not make sense, so I’m going to start by explaining this type of destructuring in 2 steps and then show how it applies in this situation.
I’ll then provide one last (cool) example which confused me initially and led me to research this topic. It’s also the exact problem described in a duplicate question.
This syntax is called Object Destructuring (MDN):
let a, b;
({a, b} = {a: 1, b: 2});
a; // 1
b; // 2
({b, a} = {c: 3, b: 2, d: 4, a: 1});
a; // 1
b; // 2
Same result – order doesn't matter!
The variables on the left (a
& b
) are assigned to the value of their corresponding key's value on the Object (right).
const obj = {a: 1, b: 2};
let {a, b} = obj;
a; // 1
b; // 2
We can store the object on the right into a variable (obj
in this case) and then use the same syntax (without parens).
Finally, let's show the words
array as an Object (arrays are just Objects under the hood).
Here's what you'll see if you type ['oops', 'gasp', 'shout', 'sun']
into Chrome's console:
const words = {0: 'oops', 1: 'gasp', 2: 'shout', 3: 'sun', length: 4};
let { length } = words;
console.log(length); // 4
Just like above, it's going to set the length
variable (left) to the value of the corresponding key in the words
Object/array (right). words[length]
has a value of 4
so the length
variable (left) now has a value of 4
as well.
From Wes Bos's Blog:
Given a person
Object, how do you create global variables referring to its properties?
const person = {
first: 'Wes',
last: 'Bos',
country: 'Canada',
city: 'Hamilton',
twitter: '@wesbos'
};
Old School:
const first = person.first;
const last = person.last;
The power of destructuring!
const { first, last } = person;
Challenge: return new array with the lengths of the respective elements in the input array.
This example is shown as a way to use arrow functions. All three solutions solve the problem, they’re just showing the evolution to finally arrive at a simple one-liner.
var materials = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
materials.map(function(material) {
return material.length;
}); // [8, 6, 7, 9]
materials.map((material) => {
return material.length;
}); // [8, 6, 7, 9]
materials.map(({length}) => length); // [8, 6, 7, 9]
On each iteration of the input array passed to map
, we are setting the {length}
parameter to the current element of materials
that is passed in as an argument:
{length} = 'Hydrogen';
This sets the length
variable to the length
property of the current string element (more on that below) and then simply returns the value of length
to the map
function which eventually returns a new array with all of the elements from the original array's lengths as its elements.
"strings" are "primitives", not objects, so they don't have properties BUT when you try to call a property such as .length
on a string, the primitive is coerced (changed) into a String Object.
Here's what a String
Object looks like in the Chrome console. Notice how it's practically the same as the Array
Object. String
(function) is a constructor, so calling new
will create a new Object constructed from that function with String
(Object) as its prototype (which is what __proto__
refers to):
Think of the code as being
const words = {0:'oops', 1:'gasp', 2:'shout', 3:'sun', length:4};
let { length } = words;
console.log(length);
Which it essentially is (nevermind all the other stuff arrays come with)
Does it make sense now?
If you add a property inside the {
and }
that belongs to the Array
, it's value is copied.
Here we check for the property constructor
. Will log constructor function
to console.
IF you add a property not belongs to an array, will return undefined
Another Example
const words = ['oops', 'gasp', 'shout', 'sun'];
let { constructor } = words;
console.log(constructor);
We are testing for something
will return undefined
const words = ['oops', 'gasp', 'shout', 'sun'];
let { something } = words;
console.log(something);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With