DevWonders

Logo
Javascript

Big Numbers

Small numbers are easy and quick to read. But what about large ones? Let's say 1000000. You probably have seen a large number like this while coding. Thankfully, javascript has a way to make these more readable, you can use underlines to separate

                            
                                console.log(1_000_000)
                            
                        

Delete

If you have an object and need to delete a property from it, you may be tempted to use the delete keyword. And that's fine, but you can solve this in a more elegant and safer way by using destructuring.

                            
                                const foo = {
                                    positionX: 50,
                                    positionY: 20,
                                    positionZ: 2
                                }
                                const { positionX, ...bar } = foo
                                console.log(bar)
                            
                        

isNan

The isNan function in JavaScript is used to determine if a value is Not a Number (NaN). It's important to distinguish between NaN and other falsy values like 0, empty strings, and false. For example, if we use the bang operator to check for a valid input, because javascript sees 0 as a falsy value, it would flip a falsy value to true, even if it's a valid one in our scenario. That's when you should use the isNan function

                            
                                let numberOfMessages = 0
                                // This would execute, even though is a valid input 
                                if(!numberOfMessages) {
                                    console.error('Error: Undefined value')
                                    return
                                }
                            
                        
                            
                                let numberOfMessages = 0
                                if(isNan(numberOfMessages)) {
                                    console.error('Error: Undefined value')
                                    return
                                }
                                console.log('You have unread messages!')
                            
                        

Nullish Coalescing

The logical OR operator (||) is used extensively to provide default values or check for truthy conditions. Developers often rely on it because of its simplicity. However, the OR operator can sometimes lead to unexpected behavior, especially when dealing with the number 0

                            
                                let tax = 0

                                const reward = tax || 10 // Default tax is none is given
                                console.log(tax) // Output: 10 
                            
                        

The intention here is to provide a base tax (10 dollars) if no values is passed. But the OR operator sees the tax ammount as falsy (because it's 0) and assigns the default value (10). This can be a bug if you actually want the code to recognize 0 as a valid score and not provide a reward. This is when the ?? operator comes in hand. It checks if the value on the left side is either null or undefined. If it is, then it uses the value on the right side. This makes it perfect for setting defaults without getting tripped up by falsy values like 0

                            
                                let tax = 0

                                const reward = tax ?? 10
                                console.log(tax) // Output: 0 
                            
                        

Optional chaining

Optional chaining is a powerful feature introduced in ES6+ that allows you to safely access nested properties within an object. It avoids long if statement to check for the properties individually and errors when dealing with potentially undefined values in the chain.

                            
                                const user = {
                                    name: 'Alice',
                                    address: {
                                      street: '123 Main St',
                                      state: 'California'
                                    },
                                  }
                                  
                                // Even if property is undefined, it's safe to access
                                const street = user?.address?.street
                                console.log(street) // Output: "123 Main St" 
                            
                        

Inline catch

When dealing with code that has promises, developers tend to encapsulate the entire block in a Try/Catch block to prevent any errors. But when dealing with simple promises, this becomes unnecessary and adds a bit of nesting too. Instead, if it's a simple error treating, you can just catch it

                            
                                const data = fetch('google.com').catch(error => console.error(error))
                            
                        

Block scope

Variables declared within a block are only accessible from within that specific block. This creates a well-defined scope for each variable, preventing unintended interactions with identically named variables in other parts of your code.

                            
                                let count = 5
                                {
                                    let count = 0
                                    console.log(count) // Output: 0
                                }
                                console.log(count) // Output: 5
                            
                        

In Keyword

The in keyword is a handy operator in JavaScript that checks if a property exists as a key within an object.

                            
                                const person = { name: 'Alice', age: 30 }
                                console.log('name' in person) // true
                                console.log('city' in person) // false
                            
                        

Dynamic Import

Imagine a scenario where you only want to load specific code based on certain conditions. JavaScript's dynamic import functionality allows you to import modules at runtime.

                            
                                if(userIsAdmin) {
                                    const lazyModule = await import('./admin.js')
                                }
                            
                        

Promise.all

Waiting for multiple asynchronous operations can be sometimes inneficient.Let's say you have to fetch a list of users and posts from an api. The data retrived from one is not necessary to fetch the other.
Promise.all() helps you get both results at once: It allows you to execute them in parallel and provides a single promise that resolves when all the individual promises have resolved.

                            
                                /* We're waiting users to finish before fetching the posts
                                Even if we don't need the users data to fetch posts */
                                const users = await fetch('https://api.example.com/users/')
                                const posts = await fetch('https://api.example.com/posts/')
                                
                                const [users, posts] = await Promise.all([
                                    fetch('https://api.example.com/users/'),
                                    fetch('https://api.example.com/posts/')
                                ])
                            
                        

Object.groupBy

Object.groupBy() allows you to categorize these objects based on a specific property. The end result is an object organized in groups. Let's take an example, you have a array of products and want to separate them between cheap and expensive:

                            
                                const products = [
                                    { name: 'Laptop', price: 500.00 },
                                    { name: 'Mug', price: 27.50 },
                                    { name: 'Headphones', price: 199.99 },
                                    { name: 'Fork', price: 2 },
                                ];

                                function categorize({price}) {
                                    if (price > 100)
                                        return 'expensive'
                                    return 'cheap'
                                }

                                console.log(Object.groupBy(products, categorize))
                            
                        
                            
                                // Output:
                                {
                                    'cheap': [
                                        { name: 'Mug', price: 27.5 },
                                        { name: 'Fork', price: 2 }
                                    ],
                                    'expensive': [
                                        { name: 'Laptop', price: 500 },
                                        { name: 'Headphones', price: 199.99 }
                                    ]
                                }
                            
                        

Array mutations

JavaScript offers several methods for manipulating arrays. However, traditional methods like sort, splice, and reverse modify the original array, and that's not a consistent behavior, since other methods like map, filter and reduce don't do that.
ECMAScript 2023 introduced a set of new methods that prioritize immutability: toSorted, toSpliced, and toReversed. These methods create new arrays, leaving the original data untouched.

                            
                                const numbers = [3, 1, 4, 5, 2];

                                const sortedNumbers = numbers.toSorted((a, b) => a - b);

                                console.log(numbers); // [3, 1, 4, 5, 2] (remains unchanged)
                                console.log(sortedNumbers); // [1, 2, 3, 4, 5]