Are you ready?
Destructuring is a quick way to get values out of objects and arrays. For example, you can extract values and assign them to variables with a single line of code.
Here's an example of how destructuring can be used with an object:
And here's an example with an array:
As you can see, destructuring makes it simple to extract values from objects and arrays and assign them to variables.
🔒 Block Scoping
The var keyword declares a global or function-scoped variable, which means it can be accessed from anywhere within the same function. On the other hand, the let keyword declares a variable that is block scoped, which means that it can only be accessed within the same block of code.
Here's an example of let-based block scoping:
As you can see, the message variable is only available within the if statement-defined block of code.
🚗 Spread Operator
Spreading the values of an array or object into a new array or object is possible with the spread operator. It's a quick way to combine arrays or objects or to turn an array-like object into a proper array.
Here's an example of how to combine two arrays using the spread operator:
Here's an example of how to use the spread operator to transform an array-like object into a real array:
A spread operator is a powerful tool for simplifying and improving the readability of your code.
🔮 Template Literals
String literals that allow you to embed expressions within your strings are known as template literals. Instead of quotes (' or "), they are defined with the backtick (`) character.
Here's an example of template literals in action:
As you can see, template literals make it simple to embed expressions within strings and allow you to write multi-line strings without using string concatenation.
💾 Arrow Functions
Here's an example of how to use the arrow function:
As you can see, arrow functions make it simple to write anonymous functions and have a shorter syntax than regular functions.
🌎 Let's Connect!
- My Twitter: @thenaubit
- My Substack (here I will publish more in-depth articles)
Top comments (48)
Nice write up @naubit , I want to add some notes to it though.
Destructuring is HORRIBLE
Here's why, and i've seen this in production code i had to debug and it took forever.
Let's say you have a "Box" and a "Bed", both have dimensions like "width" and "height"
Now, Box was added to the code first so the dev just destructured it and used width and height as variables about 50 lines lower in the code, cool, no problem.
A year later a support request came in, another dev had to add Bed to the code and they thought destructuring was great too, they put their code in between where Box is defined and above where the Box vars were used, suddenly Box's dimensions break and no one knows why. Original dev looks at their lines and goes "everything looks fine". New dev looks at their code and says "everything looks fine"....until finally someone else looks at the whole thing and goes "You @#$!%"...
Do not use destructuring use Objects so you have "box.width" and "box.length" or standard variables like "box", "box_width" and "box-height" so when you add Bed later on there is no chance of conflict.
Some might say "oh those we bad devs" and to that i'll say "We are all bad devs because we don't know what we don't know and now you know better"
Block Scoping is great, kudos indeed.
Spread Operator is nice for small arrays, but dear god do not try to use that thing on a large data set. Use a for loop, it's just as fast if not faster. And it's easier to read a year from now. Your eyes will literally glance over a spread operator thinking it's just a variable definition and leave you wondering where the hell the loop is for the data you're seeing render.
Template literals are also awesome. IE11 is finally dead dead so everything supports it.
Arrow functions are great, but personally i'm using good old function() definitions. They're just easier to find/read when going through a lot of code. The arrows just blend in too much. I get that many people love shorthand code, but you should always be writing code that someone else has to read some day, be nice about it.
Destructuring is great! Your scenario above is just a result of poor coding, not a problem with destructuring itself. You can destructure to named variables too:
It's just a tool, and sometimes it's the right one for the job, and sometimes it isn't. Sometimes destructuring is less readable than simply accessing object properties directly. It's certainly the most readable way to swap two vars that I know of:
That's my point. If you don't use it, then you can never use it badly.
I've seen it used badly more often than i've seen it done right, hence my warning not to use it.
You can choose to use it, but there is no reason to.
box.width tells you what object that width belongs to.
Your example with boxWidth means that adding a second box could potentially still be confusing for the same reason as my original comment showed.
There's just no real reason to use this, it just adds more lines of code to test since the original object definition already has everything you need.
But, again, it's gonna come down to personal preference.
Use it if you want to. I won't, and my team won't, for the reasons I stated above.
If we never use pointers how are we gonna make dynamically sized datastructures like
Vec<T>ors or the like?
That is not my point and you know it.
That's not my point. It's more a case of "Just because you CAN doesn't mean you MUST" but you do you, it's not like i'm gonna convince you otherwise.
It is. It shares the exact same logic.
If you don't use pointers you can't use them badly and run into segfaults.
How is my rhetorical question not like your point?
Contrast to my previous comment, I understand the point a little more (I think). This is a "decent" elaboration.
And sure, what you're saying is true. Just because I can use
if letdoesn't mean it would look good in the context. I think you could have made the point more general and left the message at that, instead of targeting one specific ES6 feature, considering there a quite a few features that can be abused.
As my previous message states, I believe I understand your intentions, but your delivery of it was botched horribly (IMO).
As I suggested, maybe rework it, or put more emphasis on the developer than the feature, but explaining in the way you did before I understood was not doing your view any justice.
Since this is not a terribly huge issue I don't think it would take much effort to fix.
(On an unrelated note, let me turn on my MoistCritical impression, because damn. - When you said "That is not my point and you know it." that comes off as kind of an asshat thing to say, especially when you add "but you do you". It just strikes me as "Hey. I'm overly confident people can understand me right away!". Because no, I did not understand you. @brense didn't seem to understand you either since they were on board with what I originally said. - I dunno, maybe sounding blunt wasn't your intention but I just thought I should point it out because others might get the wrong idea.)
blunt comes out when i'm having a stressful day and just want to quickly get something out of the way, so for that, my bad.
Your first reply to that prompted me to do this, lol, which i still felt like sharing now: gyazo.com/694be84381c62bd88a14540a...
I don't intend to offend people, but sometimes i'm too tired to think of the best way to say things and i just drop in the info as best i can at that moment. [probably why so much of the internet is full of horrible comments]
This is something I also find distasteful, but I feel like this, relatively, is one of the better things.
.htmlfiles, so it would be cool if they focused on that side of the community, such as allowing modules in the the browser.
I was gonna say the same thing.
I like your rebuttal, it was informative to me, and hopefully the OC as well.
I'm a little confused by your width/height example in 1. If the first dev had done:
Then width and height couldn't be overwritten. Block scoping might have made new width and height variables but only in a lexical scope, not affecting the previous code unless the new dev wrapped the original code into the new scope. That just sounds like a poor way of constructing a function that has become way too complex and is trying to do too much at once.
It would depend where the code was located, but constant dereferences with box.XYZ are not optimal and might harm performance in a loop.
That is a great point, Mike! I will try to improve my examples in future articles :)
You're only thinking about the specific example. I used a "box" as a very simple object. Now let's say box was more complex with multilevel arrays/objects within it.
Note that const still allows for child objects to be modified, so it's not really a constant in the way constants work in other languages, so you might as well use "let" since within the same scope it will have zero difference.
And you're not wrong about the dev wrapping things wrongly. My original note was just one of caution because the vast majority of devs are newbies and WILL absolutely screw this up many many times on a larger project with larger objects, while using the box.XYZ notation would simply nullify any chance of destructuring problems happening at all. THAT is all i was trying to say but it seems the comments here have largely ignored that scenario because they happen to like destructuring.
I would like to see a case/example where box.XYZ in a loop causes issues. I've not seen one, i'm open to reading more about that to see if it's really an issue or only an issue if you're looping through a million items.
You are right, it's mostly an issue if you are looping through many thousands of times, and also if there is an async function or other side effect that could change the value when you expected it to remain constant and were just not pulling it out before the loop.
I feel consistency is best served by taking values when I know I need them, it's a style thing though unless you are optimising tight loops. I'm a game programmer, I guess I'm more likely to have those huge loops :)
I've been trying to figure out how it's even possible to do this with destructuring and the only thing I could come up with is this:
If that's how your scenario happened then it's hardly a compelling argument against destructuring; but instead an argument for implementing linters and proper code review 😅
I haven't used
varin years and certainly never in code where destructuring was also supported. Using either let or const in both the destructuring statements results in an error; and in general I'd always recommend using const. Introducing mutable (or global!!!) variables into your code increases the risk of bugs.
Great answer. I agree that you'd want devs to be properly reviewing their code.
Now, that's nice for companies where the right tools are in use.
More often than not i see code written by one dev who's had no training in such things and therefore writes code that more than likely works fine most of the time, and yet has glaring holes in it to anyone who spends a lot of time debugging other people's code.
I don't know why so many people responding here [not you really, your answer was on point] presume that everyone codes the way they do, uses the tools they do, has the mentors/training they do. Most devs really do not. If we all had good training and knew all these things, then most websites wouldn't be utter pieces of crap, which frankly, they very much are.
That code should not be allowed to be committed. Use reviews to handle those cases.
Thanks for your long comment @ravavyr ! To be fair, I agree with you and I will say that in my future articles I will improve my examples and try to explain more in depth when it is a good option to use it or not.
I like to use destructuring but as @jonrandy said below, it must be done in the right places, it is just a tool that you have to use in the right place and in the right way.
About the arrow functions, I tend to agree. I like to use the old function() definitions almost everywhere but arrow functions are useful in some places.
In general I think I need to write a second part of this article going in depth with every point. I tried to make it simple and general so beginners can read and then they can keep trying and exploring, discovering the specific cases, but probably I should note these little details there.
For future reference for anyone reading the article, make sure to check this comments' thread, it is pretty useful!
Point 1 is not the fault of destructuring. There's a plethora of bugs like this, if you dont use something like typescript for type safety. Besides that, ALWAYS use
Its also worth noting that you can assign a new name to the variable while destructuring:
Ps. Just realized you can shorten that advice to: ALWAYS use
lol that's another can of worms.
I always use "Let" because half the time people use "Const" i end up changing it to Let later on because something's changed in the logic anyway.
Also the fact that Const lets you change its object properties means it's not really a constant anyway.
I do see your point to force using Const in this case just because it makes it less likely for someone to overwrite it.
However when writing code if someone's editing/changing variables, they should be thorough and confirm that variable isn't already defined within the same scope. That's not rocket science and frankly the least I'd expect even relatively new devs to be able to do. Const sometimes feels like too much hand holding and if it was really fixed constants, i'd be cool with it, but being able to modify object properties and methods means "const" is not very "constant" at all.
constdoesn't mean readonly, although you can do that with
as constin typescript, if you have to. Const means you cannot reassign the variable.
If you use
let(or even worse,
var), you open up your code for a wide range of nasty bugs that are a nightmare to debug. If you're changing a lot of
letto make the logic work, you need to seriously consider a refactor.
I eventually started to hate destructuring objects because 9/10 times devs use it they just make code less clear and more difficult to follow. This kind of stuff kills me:
Just reference the properties of the object like a normal human being!
Seeing the source object provides necessary context and avoids the ridiculous 12 line destructuring statements I see everywhere, often times just to reference these values one time later on in the code! Have we gone mad?!?!
I never had such problems with destruction. Renaming variables upon collision is completely natural.
Anyway, in case I need to use multiple times, I'd definitely assign it to 2 separate variables, which is basically destruction+renaming at the end under the hood. It's not just more performant but it can be efficiently minified while property access cannot, and the same is true for destruction.
50 lines lower I would think is a problem itself and without looking into the source it sounds like there is room for improvement. Declare variables as near as possible to usage and when possible with const.
A simple walk through would have shown the problem, either with the debugger or with console log, but in the first place I would blame the IDE that is not telling you or are you using a notepad.
As always you must know you tools and use them.
Nicely pointed out. This is valuable feedback. I will definitely think twice next time, before I go all arrow function. Never looked at it like you said: easier to spot when scanning through code.
You got a good point. Appreciate the comment
In my opinion object destructure didn't build to solve the problem you've mentioned. To solve that I recommended to use Typescript.
You missed the backtick in Template Literals
Thanks, fixing it!
Great tips. Thanks. I never really knew arrays could be destructured. Nice to know.
There is also a rest operator when destructing arrays which is sometimes useful. (Forgive me if this formats badly, I'm on mobile)
great article @naubit
Thanks nice topic
great examples and detailing @naubit! thank you
They are very useful concepts and can be applied on different occasions, it is always good to remember that they exist, thank you very much
Thanks a lot for the comment!
I'd definitely remove advanced from the title. This basically IS ES6 and every dev MUST know today to be able to work with a modern codebase.
Advanced ES6 features are more like:
Here's the best hack for ES6 developers...
move to Rust.
Same stuff as ES6 if not more. :þ
Const at least deserves to be mentioned right?
Wait isn't it a lot easier to blockscope:
Or is this a console only behaviour?
Is it possible to give a new update to the codings with code refactoring?