30 JavaScript Tricky Hacks
Mainul Hasan

Mainul Hasan @mainulspace

About: 👨‍💻 Full Stack Developer 🛠️ Tech Enthusiast | 🎓 TA & MS Student in Informatics @ University of Oslo | 🌐 Sharing #webdev, #tech insights

Location:
Oslo, Norway
Joined:
Jun 27, 2023

30 JavaScript Tricky Hacks

Publish Date: Mar 3 '24
232 26

Welcome to our curated collection of JavaScript tricks, which will help you optimize your code, make it more readable, and save you time.

Let’s dive into the depths of JavaScript functionalities and hacks that go beyond the conventional and discover the full potential of this powerful programming language.

1. Using !! to Convert to Boolean

Quickly convert any value to a boolean by using double negation.


        let truthyValue = !!1; // true
        let falsyValue = !!0; // false

Enter fullscreen mode Exit fullscreen mode

2. Default Function Parameters

Set default values for function parameters to avoid undefined errors.


        function greet(name = "Guest") {
            return `Hello, ${name}!`;
        }

Enter fullscreen mode Exit fullscreen mode

3. The Ternary Operator for Short If-Else

A shorthand for the if-else statement.


        let price = 100;
        let message = price > 50 ? "Expensive" : "Cheap";

Enter fullscreen mode Exit fullscreen mode

4. Template Literals for Dynamic Strings

Use template literals for embedding expressions in strings.


        let item = "coffee";
        let price = 15;
        console.log(`One ${item} costs $${price}.`);

Enter fullscreen mode Exit fullscreen mode

5. Destructuring Assignment

Easily extract properties from objects or arrays.


        let [x, y] = [1, 2];
        let {name, age} = {name: "Alice", age: 30};

Enter fullscreen mode Exit fullscreen mode

6. The Spread Operator for Array and Object Cloning

Clone arrays or objects without referencing the original.


        let originalArray = [1, 2, 3];
        let clonedArray = [...originalArray];

Enter fullscreen mode Exit fullscreen mode

7. Short-circuit Evaluation

Use logical operators for conditional execution.


        let isValid = true;
        isValid && console.log("Valid!");

Enter fullscreen mode Exit fullscreen mode

8. Optional Chaining (?.)

Safely access nested object properties without an error if a reference is nullish.


        let user = {name: "John", address: {city: "New York"}};
        console.log(user?.address?.city); // "New York"

Enter fullscreen mode Exit fullscreen mode

9. Nullish Coalescing Operator (??)

Use ?? to provide a default value for null or undefined.


        let username = null;
        console.log(username ?? "Guest"); // "Guest"

Enter fullscreen mode Exit fullscreen mode

Interactive banner for monday.com showcasing hands organizing workflow tasks on a digital interface with a call-to-action button ‘Show me how’.

10. Using map, filter, and reduce for Array Manipulation

Elegant ways to handle arrays without traditional loops.


        // Map
        let numbers = [1, 2, 3, 4];
        let doubled = numbers.map(x => x * 2);

        // Filter
        const evens = numbers.filter(x => x % 2 === 0);

        // Reduce
        const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);

Enter fullscreen mode Exit fullscreen mode

11. Tagged Template Literals

Function calls using template literals for custom string processing.


        function highlight(strings, ...values) {
            return strings.reduce((prev, current, i) => `${prev}${current}${values[i] || ''}`, '');
        }
        let price = 10;
        console.log(highlight`The price is ${price} dollars.`);

Enter fullscreen mode Exit fullscreen mode

12. Using Object.entries() and Object.fromEntries()

Convert objects to arrays and back for easier manipulation.


        let person = {name: "Alice", age: 25};
        let entries = Object.entries(person);
        let newPerson = Object.fromEntries(entries);

Enter fullscreen mode Exit fullscreen mode

13. The Set Object for Unique Elements

Use Set to store unique values of any type.


        let numbers = [1, 1, 2, 3, 4, 4];
        let uniqueNumbers = [...new Set(numbers)];

Enter fullscreen mode Exit fullscreen mode

14. Dynamic Property Names in Objects

Use square brackets in object literal notation to create dynamic property names.


        let dynamicKey = 'name';
        let person = {[dynamicKey]: "Alice"};

Enter fullscreen mode Exit fullscreen mode

15. Function Currying Using bind()

Create a new function that, when called, has its this keyword set to the provided value.


        function multiply(a, b) {
            return a * b;
        }
        let double = multiply.bind(null, 2);
        console.log(double(5)); // 10

Enter fullscreen mode Exit fullscreen mode

16. Using Array.from() to Create Arrays from Array-like Objects

Convert array-like or iterable objects into true arrays.


        let nodeList = document.querySelectorAll('div');
        let nodeArray = Array.from(nodeList);

Enter fullscreen mode Exit fullscreen mode

17. The for…of Loop for Iterable Objects

Iterate over iterable objects (including arrays, maps, sets, etc.) directly.


        for (let value of ['a', 'b', 'c']) {
            console.log(value);
        }

Enter fullscreen mode Exit fullscreen mode

18. Using Promise.all() for Concurrent Promises

Run multiple promises concurrently and wait for all to settle.


        let promises = [fetch(url1), fetch(url2)];
        Promise.all(promises)
        .then(responses => console.log('All done'));

Enter fullscreen mode Exit fullscreen mode

19. The Rest Parameter for Function Arguments

Capture any number of arguments into an array.


        function sum(...nums) {
            return nums.reduce((acc, current) => acc + current, 0);
        }

Enter fullscreen mode Exit fullscreen mode

Coursera Plus subscription offerings including AWS Fundamentals, Google IT Support Professional Certificate, and Cyber Security for Business Specialization.

20. Memoization for Performance Optimization

Store function results to avoid redundant processing.


        const memoize = (fn) => {
            const cache = {};
            return (...args) => {
                let n = args[0];  // assuming single argument for simplicity
                if (n in cache) {
                    console.log('Fetching from cache');
                    return cache[n];
                }
                else {
                    console.log('Calculating result');
                    let result = fn(n);
                    cache[n] = result;
                    return result;
                }
            };
        };

Enter fullscreen mode Exit fullscreen mode

21. Using ^ for Swapping Values

Swap the values of two variables without a temporary variable using the XOR bitwise operator.


        let a = 1, b = 2;
        a ^= b; b ^= a; a ^= b; // a = 2, b = 1

Enter fullscreen mode Exit fullscreen mode

22. Flattening Arrays with flat()

Easily flatten nested arrays using the flat() method, with the depth of flattening as an optional argument.


        let nestedArray = [1, [2, [3, [4]]]];
        let flatArray = nestedArray.flat(Infinity);

Enter fullscreen mode Exit fullscreen mode

23. Converting to Numbers with Unary Plus

Quickly convert strings or other values to numbers using the unary plus operator.


        let str = "123";
        let num = +str; // 123 as a number

Enter fullscreen mode Exit fullscreen mode

24. Template Strings for HTML Fragments

Use template strings to create HTML fragments, making dynamic HTML generation cleaner.


        let items = ['apple', 'orange', 'banana'];
        let html = `<ul>${items.map(item => `<li>${item}</li>`).join('')}</ul>`;

Enter fullscreen mode Exit fullscreen mode

25. Using Object.assign() for Merging Objects

Merge multiple source objects into a target object, effectively combining their properties.


        let obj1 = { a: 1 }, obj2 = { b: 2 };
        let merged = Object.assign({}, obj1, obj2);

Enter fullscreen mode Exit fullscreen mode

Ergonomic vertical mouse designed to reduce wrist strain

Optimize your programming setup with an ergonomic mouse, tailored for comfort and long coding sessions.

26. Short-circuiting for Default Values

Utilize logical operators to assign default values when dealing with potentially undefined or null variables.


        let options = userOptions || defaultOptions;

Enter fullscreen mode Exit fullscreen mode

27. Dynamically Accessing Object Properties with Bracket Notation

Access properties of an object dynamically using bracket notation, useful when the property name is stored in a variable.


        let property = "name";
        let value = person[property]; // Equivalent to person.name

Enter fullscreen mode Exit fullscreen mode

28. Using Array.includes() for Presence Check

Check if an array includes a certain value with includes(), a clearer alternative to indexOf.


        if (myArray.includes("value")) {
            // Do something
        }

Enter fullscreen mode Exit fullscreen mode

29. The Power of Function.prototype.bind()

Bind a function to a context (this value) and partially apply arguments, creating more reusable and modular code.


        const greet = function(greeting, punctuation) {
            return `${greeting}, ${this.name}${punctuation}`;
        };
        const greetJohn = greet.bind({name: 'John'}, 'Hello');
        console.log(greetJohn('!')); // "Hello, John!"

Enter fullscreen mode Exit fullscreen mode

30. Preventing Object Modification

Prevent modifications to an object using Object.freeze(), making it immutable. For deeper immutability, consider libraries that enforce immutability more thoroughly.


        let obj = { name: "Immutable" };
        Object.freeze(obj);
        obj.name = "Mutable"; // Fails silently in non-strict mode

Enter fullscreen mode Exit fullscreen mode

I hope these JavaScript tricks provide you with new perspectives on how to approach JavaScript programming.

From leveraging the concise power of template literals to mastering the efficiency of map, filter, and reduce, these JavaScript hacks will enrich your development workflow and inspire your next project.

Let these JavaScript tricks not only refine your current projects but also spark inspiration for future innovations in your coding journey.

Support Our Tech Insights

Buy Me A Coffee

Donate via PayPal button

Note: Some links on this page might be affiliate links. If you make a purchase through these links, I may earn a small commission at no extra cost to you. Thanks for your support!

Comments 26 total

  • cuihao
    cuihaoMar 4, 2024

    The article is very practical, I want to reprint your article, will mark the source of the article, if there is something wrong, please contact me, I will immediately delete

  • Khaled Md Saifullah
    Khaled Md SaifullahMar 4, 2024

    Many things got to know from this blog. Thank you so much.

  • Emmanuel Eneche
    Emmanuel EnecheMar 4, 2024

    Great article. 👏

  • Ndeye Fatou Diop
    Ndeye Fatou DiopMar 4, 2024

    Very nice ! I never knew about 11.

  • Julien Dephix
    Julien DephixMar 4, 2024

    Nice list, even though I wouldn't call these code snippets hacks but shortcuts?

    Couple of things to note.

    Hack # 1: !! is called a double bang. I don't use it as it looks a bit weird. I prefer to use Boolean().

    Hack # 11. example you provided for tagged template literals could be better as it just outputs what was passed. Looks like a copy of Wes Bos' article back in 2016:

    function highlight(strings, ...values) {
      let str = '';
      strings.forEach((string, i) => {
        str += `${string} <span class='hl'>${values[i] || ''}</span>`;
      });
      return str;
    }
    
    Enter fullscreen mode Exit fullscreen mode

    Hack #21. swapping values is much easier this way:

    let a = 2, b = 1;
    [a, b] = [b, a];
    
    Enter fullscreen mode Exit fullscreen mode

    Hack #23. converting the way you do it can cause issues if variable holds non numerical characters. Prefer .parseInt over plus.

    let n = "123A";
    console.log(+n); // NaN
    console.log(parseInt(n, 10)); // 123
    
    Enter fullscreen mode Exit fullscreen mode

    Hope this helps!

    • shArky
      shArkyMar 7, 2024

      Simply note, that #21 is more readable (for me both is good), but not easier for PC.
      In case of XOR swap we working with numbers as bits represented in memory. In case of array swap we created 2 arrays.

      • Julien Dephix
        Julien DephixMar 8, 2024

        You're right but it only creates one array actually: a temp array [b, a].
        JS then destructures it to assign values to a and be respectively.

        This is what code looks like after being transpiled:

            var a = 12;
            var b = 13;
            var _b;
            _b = [b, a], a = _b[0], b = _b[1];
        
        Enter fullscreen mode Exit fullscreen mode

        Yes, it uses more memory but we're talking about 2 numbers here so the diff in memory footprint is very minimal and not worth loosing readability.

  • Pieces 🌟
    Pieces 🌟Mar 4, 2024

    Great article! 🔥

  • Ben Sinclair
    Ben SinclairMar 4, 2024

    If the premise is to "help you optimize your code, make it more readable, and save you time", then I'd steer clear of some of these.

    Using !! to convert to boolean

    This is probably less readable, especially for people new to Javascript. There's nothing wrong with using a truthy value directly or casting things explicilty.

    "short-circuit" evaluation

    Again, there's nothing wrong with using more characters to make things easier to read, and in fact there are good reasons to keep separate things on separate lines (like always using a block for if).

    Using ^ for Swapping Values

    This hasn't been useful for at least 30 years unless you're trying to impress someone in a coding interview. It's not readable, and it doesn't save any time or effort.

    Converting to Numbers with Unary Plus

    Same deal as before. Be explicit.

    • Sean Dinan
      Sean DinanMar 5, 2024

      As a counter-point for short circuit evaluation, I've mostly switched over to it for conditionally rendering things in JSX. I stuck to ternary for years but have gradually switched over.

      I'd now say that:

      return (
        <section>
          {isLoading && <LoadingMessage/>}
          {/* ... */}
        </section>
      )
      
      Enter fullscreen mode Exit fullscreen mode

      is at least as clear as:

      return (
        <section>
          {isLoading ? <LoadingMessage/> : null}
          {/* ... */}
        </section>
      )
      
      Enter fullscreen mode Exit fullscreen mode
      • Ben Sinclair
        Ben SinclairMar 5, 2024

        I agree, for things like JSX (which still look uncomfortable to me even after a few years) it is still readable - provided you keep things simple.

    • iakovosvo
      iakovosvoMar 5, 2024

      Regarding the use of !!, I find Boolean(isThisAtruthyValue) to be more expressive and easier to read.

      • Mainul Hasan
        Mainul HasanMar 7, 2024

        Absolutely, using Boolean(isThisTruthyValue) is indeed more expressive and can be clearer to read, especially for those who are not as familiar with the nuances of JavaScript’s type coercion. It’s great that you’ve highlighted an alternative that prioritizes readability and self-documenting code.

        The choice between !! and Boolean() often comes down to personal or team preference, and the context in which the code will be read and maintained. I appreciate you bringing this up — it’s always beneficial for developers to be aware of different options that can make their intent more explicit.

        Thank you for adding to the conversation with your insightful suggestion!

    • Charles F. Munat
      Charles F. MunatMar 7, 2024

      True. And the way to convert to Boolean is Boolean(value).

    • Mainul Hasan
      Mainul HasanMar 7, 2024

      Thank you for taking the time to share your excellent thoughts. I truly appreciate your perspective and understand the concerns about readability, particularly for those new to JavaScript.

      The intention behind showcasing these techniques, such as using !! to force a boolean context or the unary + for type conversion, was to present a spectrum of approaches that developers might encounter in practice or find useful in specific scenarios.

      It’s a valid point that explicit casting and traditional methods can enhance clarity, especially for less experienced developers. The utility of these tips often depends on the context in which they’re used and the audience interpreting the code.

      Regarding the bitwise XOR for value swapping, I agree that it’s not a common practice in every day coding. It’s indeed more of a fun trick that could be useful to understand when reading legacy code or preparing for interviews, as you mentioned.

      Ultimately, the goal is to inspire developers to think critically about the tools at their disposal and to choose the best tool for the task, balancing efficiency and readability.

      Thanks again for providing friendly suggestions and feedback.

    • João Filipe Ventura Coelho
      João Filipe Ventura CoelhoMar 8, 2024

      Was about to comment the exact same thing

  • Fiji
    FijiMar 5, 2024

    Sweet! Thanks

  • Lotfi Jebali
    Lotfi JebaliMar 5, 2024

    console.table() :))))

  • John Harding
    John HardingMar 6, 2024

    Cool! I never knew about #11. It took me a while to figure it out - and, as another poster (@joolsmcfly) mentioned, your example just returns the same string you passed in. However, the sample he provided has an empty span at the end and doesn't use reduce...

    So, here's my submission as a better example (which is entirely subjective of course):

    const spanify = (strings, ...values) => 
      strings.reduce((resultSoFar, stringPart, valueIndex) => 
        `${resultSoFar}${stringPart}${values[valueIndex]?`<span class='foo'>${values[valueIndex]}</span>`:''}`, '')
    
    spanify`My name is ${'John'}` // "My name is <span class='foo'>John</span>"
    
    Enter fullscreen mode Exit fullscreen mode
  • Daniel Ordonez
    Daniel OrdonezMar 6, 2024

    For cloning objects with depth I prefer structuredClone() instead of the spread operator (#6) so you don’t store references to objects inside the old object in the clone.

  • Charles F. Munat
    Charles F. MunatMar 7, 2024

    In dev terms, "tricky" is bad. Nothing you do in code should ever be "tricky". That's a fail. Hacks should also be avoided except in extraordinary circumstances.

    But most of these are not "hacks" and most are not "tricky". How these listicles that have nothing but collections of old info keep getting onto the DEV Community Digest list while far better and more interesting articles languish in obscurity is quite disturbing.

    What is up with that?

    • John Harding
      John HardingMar 7, 2024

      @chasm - Yes, the article might be slightly mistitled- but it is a good list. I've been writing code for 30+ years and I learned from #11 (even though it wasn't a great example - it piqued my interest and made me look more). I may even have already known that info but forgotten it.

      As a listicle I could scan it quickly (and I cringed at #21!) - it's actually one of the better articles because it's so terse.

      The constant publishing of "old" information is thus useful because it can remind all of us of little bits and pieces. As to why other articles languish - who knows? Maybe, just maybe, that's more the subjectivitiy of what you think is interesting?

      @mmainulhasan - perhaps a better title "30 useful JS tips and tricks" ?

  • Sezgin İbiş (incelemeelemani)
    Sezgin İbiş (incelemeelemani)Mar 7, 2024

    Thanks for you article.

  • João Angelo
    João AngeloMar 10, 2024

    Hi M Mainul Hasan,
    Your tips are very useful
    Thanks for sharing

  • Serantu
    SerantuApr 1, 2024

    Thanks for the resource!

  • URIAN VIERA
    URIAN VIERAApr 9, 2024

    Excelente amigo.

Add comment