You Might Not Know These: 5 Important and Lesser-Known Features in JavaScript

Sonay Kara - Oct 2 - - Dev Community

Even if you have been using JavaScript for years, you may not have discovered some advanced features. In this article, we will discuss important and lesser-known features in JavaScript.

1. Safe Access with Optional Chaining (?.)

Accessing a value in a deeply nested structure of objects in JavaScript can sometimes pose a risk of errors. If a value deep down is undefined or null, this can lead to an error. The optional chaining operator (?.) eliminates this issue.

Example:

const user = {
  name: 'John',
  address: {
    city: 'New York'
  }
};

console.log(user.address?.city); // 'New York'
console.log(user.address?.zipcode); // undefined, does not throw an error
Enter fullscreen mode Exit fullscreen mode

2. Nullish Coalescing (??)

The nullish coalescing (??) operator in JavaScript returns an alternative value when a value is null or undefined. This operator is particularly useful for providing a default value when a variable has no value or is undefined.

Examples:

et x = 0;
let y = x ?? 42; // returns 0 because 0 is not null or undefined
console.log(y);
Enter fullscreen mode Exit fullscreen mode
function getConfig(config) {
    return config ?? { timeout: 1000, retries: 3 };
}

let userConfig = null;
let finalConfig = getConfig(userConfig); // { timeout: 1000, retries: 3 } 
console.log(finalConfig);
Enter fullscreen mode Exit fullscreen mode

3. Performance Improvement with Debouncing

Debouncing is a technique that ensures a function is executed only once within a certain timeframe. This is particularly useful for user interactions (e.g., typing, scrolling) that trigger events frequently. Debouncing is commonly used to initiate a process (e.g., an API call) after a user has completed an action.

In a search input field, instead of making an API call for every keystroke, debouncing allows the API call to occur only when the user stops typing:

  • Prevents server overload: Fewer requests are sent, allowing the server to operate more efficiently.

  • Reduces latency: Users receive quicker responses.

  • Enhances user experience: Users wait for suggestions to appear only after stopping typing.

Example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Debounce Example</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        #searchInput {
            padding: 10px;
            width: 300px;
            font-size: 16px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        #result {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Search Example</h1>
    <input type="text" id="searchInput"/>
    <div id="result"></div>

    <script>
        // Debounce function
        function debounce(func, delay) {
            let timeoutId;
            return function(...args) {
                clearTimeout(timeoutId);  // Clear previous timer
                timeoutId = setTimeout(() => func.apply(this, args), delay);  // Set a new timer
            };
        }

        const search = debounce((query) => {
            console.log(`Searching for ${query}`);
            // You can make an API call here
            document.getElementById('result').innerText = `Searching for results: ${query}`;
        }, 300);

        // Listening to input event
        document.getElementById('searchInput').addEventListener('input', (event) => {
            search(event.target.value);
        });
    </script>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

4. Managing Objects with Proxy

Proxy allows you to intercept and redefine operations on an object. This feature is useful for defining customized behaviors before performing operations on an object.

Example:

const target = {
  message: 'Hello'
};

const handler = {
  get: function(obj, prop) {
    if (prop in obj) {
      return obj[prop];
    } else {
      return `Property ${prop} does not exist`;
    }
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message); // Hello
console.log(proxy.nonExistent); // Property nonExistent does not exist
Enter fullscreen mode Exit fullscreen mode

5. Preventing Duplicate Values with Set and WeakSet

Both structures can be used to prevent duplicate values. Here are examples of how to use each structure:

  • Preventing Duplicate Values with Set
const numbers = [1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9];
const uniqueNumbers = [...new Set(numbers)];

console.log(uniqueNumbers); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
Enter fullscreen mode Exit fullscreen mode
  • Preventing Duplicate Values with WeakSet
const uniqueObjects = new WeakSet();

const objA = { name: 'Alice' };
const objB = { name: 'Bob' };
const objC = objB; // Same reference

// Adding values
uniqueObjects.add(objA);
uniqueObjects.add(objB);
uniqueObjects.add(objC); // This won't be added since it's a reference to objB

console.log(uniqueObjects); // WeakSet { ... } (shows objA and objB)
Enter fullscreen mode Exit fullscreen mode

Conclusion

These features provide tools to fully leverage the power and flexibility of JavaScript. Don't hesitate to incorporate these features into your projects to make your code more performant, clean, and maintainable.

. . . . . . . . . .
Terabox Video Player