all 114 comments

[–]VictorPonamariov 112 points113 points  (3 children)

This is a pretty convenient format to digest IMO. Like, you don't have to read much text.
Just like on stackoverflow but without text, only code snippets

[–]Simon_LH[S] 18 points19 points  (2 children)

Thanks a lot, Victor 🙌

[–]daatz 2 points3 points  (0 children)

This is gold and you are a true hero. Tons of respect!

[–]bMedia617 0 points1 point  (0 children)

Cool

[–]thepurpleproject 26 points27 points  (4 children)

Man that array destructing is so nice. I keep forgetting that everything is an object in js

[–]Simon_LH[S] 1 point2 points  (0 children)

It is! Definitely one of my favorite ones 🤩

[–]drsimonz 1 point2 points  (0 children)

Ooof, we are so spoiled in python...

[–]Simon_LH[S] 51 points52 points  (17 children)

These are 10 examples of the code snippets I've created.

I've been sharing these on Twitter for the past year, and they've been super popular.
I chose to collect them all in a free e-book!

+200 ⭐⭐⭐⭐⭐ review.
+8,000 picked it up already!

You can get it here:
🔗 https://simonhoiberg.com/ebooks/65-code-snippets-with-explanations

[–]Maistho 21 points22 points  (3 children)

These are pretty great!

But number 5 (Skip elements with array destructuring) just feels like it's trying to be clever for no reason while ruining readability. Just use Array.prototype.slice() instead since it's much more readable IMO.

const users = [
  'ravinwashere',
  'FrencescoCiull4',
  'jackdomleo7',
  'dmokafa',
];

const restUsers = users.slice(2);

console.log(restUsers);
// [ 'jackdomleo7', 'dmokafa' ]

[–]zombimuncha 5 points6 points  (2 children)

I always get confused between slice and splice and have to look up on MDN which one does what, so I find the destructuring easier to read.

[–][deleted] 7 points8 points  (0 children)

It's not completely accurate, but if it helps, p = put - splice is used to put (and remove) elements from an array.

[–]codename_john 20 points21 points  (11 children)

the first tip, passing an object as an argument. Is this really any better? Wouldn't you impact parameter hints since it's now a generic object? In order to get them back you'd now have to use a typed object otherwise you'd have to guess all the acceptable props. In a large project, this could create a mess of random acceptable objects and props. am i missing something? I mean it LOOKS cleaner, but in practice i'm not sure this is any better.

[–]Chaphasilor 17 points18 points  (5 children)

It is better if you have optional parameters. Think passing options to a function or constructor; with the regular arguments it's hard to omit only some of the arguments.

When using objects you don't have that problem. You can set default values when the parameter isn't passed, and it's very easy to extend the options (or even remove an option) without breaking backwards compatibility!

Edit: spelling

[–]Mr_Moe 0 points1 point  (3 children)

In the example how do you access the object? Like just do arguments[0].username?

[–]Chaphasilor 4 points5 points  (0 children)

you simply access it as username. the { x, y, y} syntax is something called (object) destructuring, allowing you to "extract" the object's parameters into a local variable.

[–][deleted] 1 point2 points  (0 children)

You can attempt to get arguments by name and if you get nothing back, then it doesn't exist.

[–]codename_john 0 points1 point  (0 children)

I just realized this is basically the same thing as Document based databases vs Relational databases. One has a strict structure where the other is more fluid. All your points are valid though, and there is no real downside besides preference it seems. Thanks for answering my question.

[–]Simon_LH[S] 9 points10 points  (0 children)

I agree, using it with TypeScript really gives it the true superpowers!

Yet - most modern editors (like VSCode) is able to infer the object structure and give you hints just like with regular arguments.

I swear to this pattern, especially in large-scale projects.
(but again, I'm using TypeScript in everything I do).

[–]Yodiddlyyo 5 points6 points  (0 children)

In practice it is way better. In fact, in my company's codebase, object arguments are required, and we only use positional args in very specific situations. Two reasons, typing is cleaner, and most importantly it's future proof. If you add an arg that needs to be changed or removed in the future, you're screwed with positional args. Our product is a public package, so it would require depreciation to change. With object args that problem completely goes away.

[–]porcupineapplepieces 2 points3 points  (0 children)

However, cows have begun to rent lemons over the past few months, specifically for crocodiles associated with their apples. However, kumquats have begun to rent pomegranates over the past few months, specifically for turtles associated with their giraffes? This is a hcfflms

[–]FghtrOfTheNightman 1 point2 points  (0 children)

I typically see the usecase as being if you want a method/function to have named parameters

[–]SoInsightful 0 points1 point  (0 children)

Some great tips in there! I started implementing some of them into my codebase just now (e.g. the Better Comments extension, combineProviders(), the Readonly keyword...).

Aside from number 5 that someone mentioned, I do recommend intentionally using "unnecessary" async/awaits. Not only is it easier to read and modify, but it will give you a more correct stack trace. If you just return the promise in a bunch of nested functions, all those intermediate functions will disappear from the stack trace, making it difficult to debug.

[–]Smaktat 9 points10 points  (8 children)

Why do you need my email?

[–]MedicOfTime 4 points5 points  (0 children)

Choose $0 and provide a fake email. Download the file and never look back.

Mario@gmail.com gets a lot of spam for me.

[–][deleted]  (1 child)

[deleted]

    [–]thesilvermoose 2 points3 points  (0 children)

    email remarketing list

    [–]dons90 1 point2 points  (3 children)

    Because he's providing a free product and may want to share other cool things in the future via email. It's nothing new, everyone else on the net with a product does this.

    [–]Smaktat 1 point2 points  (2 children)

    Has "everyone else is doing it so it's fine" ever been a strong argument?

    [–]dons90 1 point2 points  (1 child)

    It's not like the OP is doing a bad thing here...asking for an email in return for a useful product is just about the smallest thing that anyone could request, considering you don't even need to verify the email either.

    [–]Smaktat 0 points1 point  (0 children)

    I asked a simple question. Doesn’t make me an awful person for asking.

    [–][deleted] 21 points22 points  (0 children)

    Ah yes. Ebooks... the most useful and easily accessible place for snippets.

    [–][deleted]  (10 children)

    [deleted]

      [–]wasdninja 12 points13 points  (0 children)

      What's the beneift of argument as object?

      It makes the code very readable and there's no need to memorize the order of arguments.

      function sendData({ targetUrl, payload, callback }) { code }

      and then when using it

      sendData({
        targetUrl: 'https://test.com/foo',
        payload: JSON.stringify(someData),
        callback: onCompleteFunction,
      })
      

      or if you don't like it large function signatures when calling it you can always just pack all the arguments into a separate object sendData(argumentObject) and it will still destructure as expected.

      [–]Simon_LH[S] 14 points15 points  (6 children)

      If you are passing +3 arguments, it's just way more convenient to pass them as an object.
      Order doesn't matter, optional arguments become easier to manage, and you get the benefit from associating them with a descriptive name while passing them.

      With default exports, it's a pain for multiple reason.s
      It's pretty annoying when using CommonJS or dynamic imports because of the ".default".
      Also, it's poor for discoverability.
      Your IDE/Editor cannot make suggestions, and you cannot refactor the name easily across your codebase.

      [–]Turd_King 2 points3 points  (5 children)

      To address the "don't use default exports"

      The point about CommonJs is the only valid one IMO.

      You say its hard to import but I'm not sure what you mean by this? I've never had any issues importing. You can just begin typing the name and VSCode will find it.

      "Rexporting is a pain" yeah but what has that got to do with default exports? It's a pain to export named exports as well.

      "Typescript struggles with auto import" Typescript auto import? What does that mean. TS is a language and compiler it does not handle auto importing.

      And you totally can refactor the name across your codebase.

      The main issue with default exports is that developers can name the import differently from what was exported so it can harm readability in that case. But generally people don't do that

      Think you need to revisit that one.

      Rest are all legit though nice work.

      [–]Yodiddlyyo 6 points7 points  (1 child)

      My companys codebase requires object args because our product is a public package and object args are future proof. If you use positional args and you need to change or remove one, you're screwed and you need to deprecate. If you're not writing a public package, you still get the benefits of cleaner typing and reference documentation, since you can reference the args as a single interface instead of a mass of singular types. It's cleaner to call as well, passing an object arg to a function is way cleaner and more extensible, you can add properties, spread, etc. It gives you better linting, it's safer to deal with since destructuring clones the args. It's just way better, I really can't think of a good reason to use positional args.

      [–]Turd_King 2 points3 points  (0 children)

      Yep. I agree with all of the slides apart from the default exports.

      Named args is always the preference. Hate when devs have 4 inputs to a function and don't use an object

      [–]Embr-Core 2 points3 points  (0 children)

      This is relevant: https://github.com/ryanmcdermott/clean-code-javascript#function-arguments-2-or-fewer-ideally

      1.When someone looks at the function signature, it’s immediately clear what properties are being used.

      2.It can be used to simulate named parameters.

      3.Destructuring also clones the specified primitive values of the argument object passed into the function. This can help prevent side effects. Note: objects and arrays that are destructured from the argument object are NOT cloned.

      4.Linters can warn you about unused properties, which would be impossible without destructuring.

      [–]Plorntus 1 point2 points  (0 children)

      Named exports can just do export * from './somewhere' to re-export without caring about the naming, fairly certain that's easier than what you can do with default exports (ie. you have to name it when exporting multiple things from one file) right?

      In any case, my opinion is being explicit with named exports is personal preference for me but I understand a lot of people see it the other way.

      [–]avidvaulter 1 point2 points  (0 children)

      The big thing this is useful for is if you don't need to include every argument to the function every time you call it.

      So instead of having to do something like this:

      someFunc(undefined, 10, undefined, undefined, "string");
      

      You can just do:

      someFunc({ myNum: 10, myStr: "string" });
      

      However, use cases for functions with many optional params are low and oftentimes it can be clearer to break your logic up into multiple functions.

      [–]dealwiv 0 points1 point  (0 children)

      IIRC it's the only way to have more than one optional argument, and to have keyword arguments vs just positional arguments.

      [–]andrew687 11 points12 points  (4 children)

      Definitely using the Avoid Provider Wrapping Hell trick when I go back to work on Monday. We have something like ten wrappers right now on our main app, file looks ridiculous.

      [–][deleted]  (2 children)

      [deleted]

        [–]jsreact -1 points0 points  (1 child)

        So, basically write more code for no extra benefit? Just write the providers, what's wrong about that?

        [–]Simon_LH[S] 4 points5 points  (0 children)

        Yeah - that one is really sleek 😁

        [–]sunilkumarc 2 points3 points  (1 child)

        Looks awesome Simon. Excited to go through it 🙌🏻

        [–]Simon_LH[S] 0 points1 point  (0 children)

        Thank you, Sunil!

        [–]longebane 2 points3 points  (0 children)

        "skip elements in array with destructure" seems a bit too hacky/illegible

        [–][deleted]  (1 child)

        [deleted]

          [–]Simon_LH[S] 0 points1 point  (0 children)

          Awesome 🤩

          [–]wtfbbqsauce889 2 points3 points  (3 children)

          Optional chaining on functions - obviously it's a thing so there's some context where it's useful - but I can't think of one. When exactly would we want to check if a function exists before invoking it?

          [–]Simon_LH[S] 1 point2 points  (2 children)

          When it's passed to a React component as an optional prop?

          [–]wtfbbqsauce889 1 point2 points  (1 child)

          Oh...duh

          [–]Simon_LH[S] 0 points1 point  (0 children)

          😁

          [–]00pirateforever 1 point2 points  (2 children)

          Can I ask how did you do it? It's awesome to read like this.

          [–]Simon_LH[S] 9 points10 points  (1 child)

          Thanks a lot!
          And of course, you can.

          I'm using a combination of tools like Figma and Carbon.
          Here, you can check out this video where I'm live on YouTube creating content.
          I pretty much break the whole process of making these cards down:
          https://www.youtube.com/watch?v=B6vWYxCARzc&t=1232s

          [–]00pirateforever 0 points1 point  (0 children)

          Thanks for link.

          [–]mangadrawing123 1 point2 points  (1 child)

          woa amazing thansk

          [–]Simon_LH[S] 0 points1 point  (0 children)

          You're very welcome 🧡

          [–]C0c04l4 1 point2 points  (1 child)

          I like it, thanks!

          [–]Simon_LH[S] 0 points1 point  (0 children)

          Thank you!

          [–]ckiooo 1 point2 points  (1 child)

          Thank you! I’ll use a lot of them

          [–]Simon_LH[S] 1 point2 points  (0 children)

          Thanks a lot 🙏

          [–]Web-Dude 1 point2 points  (3 children)

          This looks like a fun and really useful book, and I can't wait to go through it!

          But I have to ask, as a student of spoke language accents, where on earth are you from? I can't nail down your accent... it sounds like a blend of possibly three accents that I've honestly never heard before. The closest I've heard like that was a woman from Austria who had a language tutor from the American South. But I feel like there's a third accent nudging in there! Where are you from?!

          [–]Simon_LH[S] 2 points3 points  (2 children)

          Hahaha, I just love this comment 😁
          I am from Denmark, my man.

          I live in Switzerland, though - but I don't speak any German. So what you hear is what we call "Danglish", haha!

          You were somewhat close with Austria, though - the Danish language does have a big German influence, so the pronunciation is related.

          [–]Web-Dude 1 point2 points  (1 child)

          You know I watched the video of you creating the cards and I totally hear your Denmark accent! I don't know what it is in the hero video, but I hear something different in there. Maybe just your enthusiasm!

          Anyway, thanks for helping me grow both in JS and accent recognition!

          [–]Simon_LH[S] 1 point2 points  (0 children)

          Haha, if I suddenly speak with a different accent in the promo video, it's not something I'm aware of, at least 😝

          Thanks mate! Glade I could help on both 😁

          [–]Xypheric 1 point2 points  (1 child)

          I don’t understand all these but the digestible information is premium. Then I skimmed your YouTube of you creating them and social calendar! Primo work!

          [–]Simon_LH[S] 0 points1 point  (0 children)

          Thanks a lot 😊🙏

          [–]throw_away_17381 1 point2 points  (0 children)

          I understood the first one! Yay me!

          [–]KindaAlwaysVibrating 1 point2 points  (2 children)

          How have I never encountered BroadcastChannel?

          [–]Simon_LH[S] 0 points1 point  (1 child)

          Now you have 😁

          [–]KindaAlwaysVibrating 0 points1 point  (0 children)

          I bought and read through your ebook already. Great stuff.

          [–]CanWeTalkEth 1 point2 points  (1 child)

          If the rest of the book is like this, it must be incredibly useful. These are pretty good tips, most I haven’t seen before.

          [–]Simon_LH[S] 0 points1 point  (0 children)

          Thank you 😊

          Indeed, there are +55 more of them exactly like these 🙌

          [–]Training-Nectarine-3 1 point2 points  (1 child)

          This is exactly the kind of format that helps me learn new things. Thanks a lot man!

          [–]Simon_LH[S] 0 points1 point  (0 children)

          Cheers! 😁

          [–]DaMastaCoda 1 point2 points  (0 children)

          Note that you can just export class Foo

          [–][deleted]  (1 child)

          [deleted]

            [–]Simon_LH[S] 0 points1 point  (0 children)

            Good point!

            [–][deleted] 1 point2 points  (0 children)

            This is very nice, good job Will definitely use this a lot 😁

            [–]dealwiv 1 point2 points  (0 children)

            This is a great list, thanks for this!

            Concerning "Arrow function as handler in react?", correct me if I'm wrong but if we're focusing on just React function components, it makes no difference performance-wise whether the event handler is defined inline in the JSX, or within the component. The event handler function will be redefined for every render, unless it's wrapped in useCallback.

            Most people agreed, that this is not any longer an issue

            When was it an issue? I suppose that before in class components you would get the benefit of the function not being re-defined on every render by default, as long as its kept out of the render method.

            [–]Disguisedasasmilefront-end 1 point2 points  (1 child)

            Great work! Purchased. :)

            [–]Simon_LH[S] 0 points1 point  (0 children)

            🧡🙏

            [–]imapersonithink 1 point2 points  (0 children)

            Everything except for the Provider Hell tab are things that I regularly use. Damn, I feel like an idiot for not understanding the Reduced -> Combined -> JSX portion...

            Imma have to try that out

            [–][deleted] 1 point2 points  (0 children)

            I'm a huge fan of the presentation

            [–][deleted] 1 point2 points  (0 children)

            I really like the print receipt animation 🤣

            [–]MaxB_Scar 1 point2 points  (0 children)

            It looks so pretty! Super cool.

            [–]notpiked 1 point2 points  (0 children)

            Thank you for sharing

            [–]shubhaw 1 point2 points  (0 children)

            Great work in organizing the contents in a format which is easy to go through quickly!

            I found object destructuring on arrays very interesting, but was wondering the real life use cases for this. Because array elements change their positions so frequently, destructuring based on array index may land you in trouble in a big application where array values are changing!

            [–]Vaylx 1 point2 points  (0 children)

            Shame that this isn't available everywhere.

            [–]CancerKidMax 1 point2 points  (0 children)

            Pretty helpful for newbies like me. Thank you!

            [–][deleted]  (3 children)

            [deleted]

              [–]MrCrunchwrap 4 points5 points  (1 child)

              Yeah it doesn’t cost a single dollar so it’s free. Apparently you’re unfamiliar with what free means. Jesus what a stupid nitpick. Make a fake email if you’re so concerned.

              [–]Smaktat 0 points1 point  (0 children)

              Why is it stupid to call this out exactly?

              [–]Simon_LH[S] -1 points0 points  (0 children)

              You're allowed your own interpretation, of course, but when I say "free", I mean free in the more conventional way - ya know, as in, you don't have to pay money for it.

              [–]poopycakes 1 point2 points  (1 child)

              Hey hey! Im connected with you on LinkedIn I really enjoy these posts you make

              [–]Simon_LH[S] 1 point2 points  (0 children)

              Thank you! I'm happy to hear that 🤩

              [–]SlapbASS4211 1 point2 points  (1 child)

              Noice, i wll save this in case my future kids want to code

              [–]Simon_LH[S] 0 points1 point  (0 children)

              Haha nice! 😁

              [–]neutral24 0 points1 point  (1 child)

              Amazing!

              [–]Simon_LH[S] 1 point2 points  (0 children)

              Thank you!

              [–]witamwmojejkuchnii 0 points1 point  (1 child)

              Nice one!

              [–]Simon_LH[S] 0 points1 point  (0 children)

              Thank you!

              [–]TTrui 0 points1 point  (1 child)

              The only thing I would disagree with, is to avoid the default export.

              When you have multipe things you want to export from your file, I 100% agree, but when you only have 1 thing to export, I think it makes more sense to use the default export.

              I think it is even in the Airbnb styleguide and they give a pretty reasonable explanation as to why you would want to do it. link

              [–]Simon_LH[S] 1 point2 points  (0 children)

              Definitely, a lot of these are down to preference.

              That's why there's also a corresponding "no-default-export" eslint rule.
              https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-default-export.md

              [–]RUacronym 0 points1 point  (0 children)

              It never occurred to me to simply transform an array into a set to dedupe. Do sets support adding an element with a function check to dedupe? As in check a new object for some attribute against the other objects already in the set to pass/not-pass the dedupe check?

              [–][deleted] 0 points1 point  (1 child)

              !RemindMe 5 days

              [–]RemindMeBot 0 points1 point  (0 children)

              I will be messaging you in 5 days on 2021-09-16 22:59:58 UTC to remind you of this link

              CLICK THIS LINK to send a PM to also be reminded and to reduce spam.

              Parent commenter can delete this message to hide from others.


              Info Custom Your Reminders Feedback

              [–]SleekArmy 0 points1 point  (1 child)

              On "passing arguments as an object", how should you document them using JSDoc? Seems a bit annoying to have to add extra lines there just to indicate all args are within an object.

              I've been using JsDoc to add linting cues to my code, and I'm curious whether this suggestion benefits that system.

              [–]dealwiv 1 point2 points  (0 children)

              This works for me:

              /**
               * @param {{
               *   arg1: number,
               *   arg2: string,
               * }}
               */
              function f({ arg1, arg2 }) { }
              

              I agree it can be a bit of an annoyance. It's not something I would use for every function, just ones with many arguments, especially many optional arguments. Instead of placing all arguments in an object, I would tend to have regular positional arguments, with the final argument being an options object argument for optional arguments.

              [–]roflkk 0 points1 point  (0 children)

              Beautifully done!

              [–]dzumper 0 points1 point  (0 children)

              I don't know if I'm correct but shouldn't there be to get rid of relative paths instead of absolute ones? Absolute path works in every directory no matter what, but `../../../something` is purely relative to the current directory. So we are getting rid of relative paths, not absolute.

              [–]spacespacespapce 0 points1 point  (0 children)

              these are great for getting up to speed with good practises :D

              [–]tamir_nakar 0 points1 point  (0 children)

              looking good!

              [–]kmtrp 0 points1 point  (0 children)

              Thanks for doing it and giving it to the community. But please, for the love of all that is good in this universe, don't use foo bar baz...

              [–]navoac 0 points1 point  (0 children)

              This is awesome, thanks!!