Member-only story

Underused JavaScript Gems: Tips Every Fullstack Python Developer Should Know

Jenny Ouyang
5 min readOct 18, 2024

As a fullstack engineer, I spend the majority of my time writing backend code in Python. However, I also dive into JavaScript frequently when working on the frontend. Over time, I’ve discovered that while JavaScript is a powerful language, it hides some of its best tools under the hood. In this article, I’ll introduce you to some underused JavaScript gems that have not only made my code cleaner but also more efficient and readable. If you’re a Python developer like me, these tricks will help you write slicker JavaScript in no time.

If you don’t have medium subscription, you can still access the complete article via my friend link.

Let’s dive into some tips, with explanations, code examples, and even a bit of performance discussion where relevant!

1. Optional Chaining (?.)

What it is: Optional chaining is a great shortcut when it comes to accessing deeply nested object properties. It avoids errors like “Cannot read property ‘X’ of undefined” when accessing properties that might not exist.

Code Example:

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

console.log(user?.address?.city); // Output: "New York"
console.log(user?.contact?.phone); // Output: undefined (no error)

Time & Space Usage: Optional chaining doesn’t have significant performance overhead compared to traditional checks (&& operators), and it improves readability.

2. Nullish Coalescing (??)

What it is: This operator is similar to ||, but it only checks for null or undefined rather than all falsy values (like 0 or ""). This is perfect when you want to provide a default but still allow for falsy values like 0 or false.

Code Example:

const count = 0;
const defaultCount = count ?? 10;
console.log(defaultCount); // Output: 0

Time & Space Usage: It’s as efficient as || in terms of performance but adds the advantage of avoiding unwanted fallbacks for values like 0.

3. Destructuring with Defaults

What it is: Destructuring allows you to easily extract values from objects or arrays. You can also set default values if certain keys are missing.

Code Example:

const user = { name: 'Alice' };
const { name, age = 30 } = user;
console.log(age); // Output: 30 (default)

Time & Space Usage: Destructuring is both time and space-efficient, especially compared to the traditional way of extracting values using dot notation.

4. Short-Circuiting Conditional Assignment

What it is: You can use logical operators (&& and ||) to conditionally assign values. This eliminates the need for verbose if statements.

Code Example:

const user = { isLoggedIn: true };
const welcomeMessage = user.isLoggedIn && 'Welcome back!';
console.log(welcomeMessage); // Output: "Welcome back!"

Time & Space Usage: This is faster than writing an explicit if statement since it’s a single logical operation.

5. Array map() with Destructuring

What it is: You can destructure array items directly inside the map() function, which makes your code more readable when extracting multiple properties from an array of objects.

Code Example:

const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
];

const names = users.map(({ name }) => name);
console.log(names); // Output: ["Alice", "Bob"]

Time & Space Usage: This approach is both time-efficient and space-efficient because the map operation runs in O(n) time and doesn’t create any extra overhead.

6. Array filter() with Boolean

What it is: When you need to remove all falsy values (e.g., null, undefined, 0, false), using Boolean as a callback to filter() can clean up your code.

Code Example:

const arr = [0, 1, false, 2, '', 3, null];
const filtered = arr.filter(Boolean);
console.log(filtered); // Output: [1, 2, 3]

Time & Space Usage: This approach has O(n) time complexity and is space-efficient as it filters in-place, avoiding additional data structures.

7. Spread Operator for Cloning and Merging Objects

What it is: The spread operator (...) makes it easy to clone objects or merge multiple objects into one. It’s cleaner than using Object.assign() and ensures immutability in many cases.

Code Example:

const user = { name: 'John', age: 30 };
const clonedUser = { ...user };
console.log(clonedUser); // Output: { name: 'John', age: 30 }

const updatedUser = { ...user, age: 35 };
console.log(updatedUser); // Output: { name: 'John', age: 35 }

Time & Space Usage: Spreading objects is faster than using Object.assign(). Both time and space complexity are O(n), but the code remains more readable.

8. Template Literals for Cleaner String Concatenation

What it is: Template literals simplify string concatenation by embedding expressions directly into strings. No more + concatenation!

Code Example:

const name = 'John';
const greeting = `Hello, ${name}!`;
console.log(greeting); // Output: "Hello, John!"

Time & Space Usage: Slightly faster than concatenation with +, especially for large, multi-line strings. It also improves readability.

9. Object Shorthand

What it is: If the variable name is the same as the key in an object, you can use shorthand syntax to clean up your code.

Code Example:

const name = 'Alice';
const age = 25;
const user = { name, age };
console.log(user); // Output: { name: 'Alice', age: 25 }

Time & Space Usage: There’s no overhead here, but it drastically improves code readability.

10. Array reduce() for Complex Transformations

What it is: While most people use reduce() to sum numbers, it’s capable of more complex transformations, like converting an array into an object.

Code Example (Sum Numbers):

const arr = [1, 2, 3, 4];
const sum = arr.reduce((acc, num) => acc + num, 0);
console.log(sum); // Output: 10

Code Example (Array to Object):

const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];

const userMap = users.reduce((acc, user) => {
acc[user.id] = user;
return acc;
}, {});

console.log(userMap);
// Output: { 1: { id: 1, name: 'Alice' }, 2: { id: 2, name: 'Bob' } }

Time & Space Usage: reduce() is O(n) in both time and space complexity. It’s efficient for reducing arrays into new structures, especially when you want to avoid looping twice.

Conclusion

It’s easy to get stuck in the unoptimized basics, especially when you’re switching between Python and JavaScript as often as I do, but once you start incorporating these tips, you’ll realize how versatile and expressive JavaScript can be. These little tricks help bridge the gap between back-end logic and front-end rendering, making both the codebase and the development process much smoother.

So, I encourage you to take these tools and start experimenting in your own projects. And remember, JavaScript is just as much about efficiency as it is about style. The more you explore, the more shortcuts and optimizations you’ll discover. Happy coding!

Sources:

  1. MDN Optional Chaining
  2. MDN Nullish Coalescing Operator
  3. MDN Destructuring Assignment
  4. MDN Logical AND (&&)
  5. MDN Array.prototype.map()
  6. MDN Array.prototype.filter()
  7. MDN Spread Syntax
  8. MDN Template Literals
  9. MDN Object Initializer Shorthand
  10. MDN Array.prototype.reduce()
Jenny Ouyang
Jenny Ouyang

Written by Jenny Ouyang

✨️ Programmer | Parent | PhD exploring the future of GenerativeAI. https://jennyouyang.substack.com/ Building products: https://findinfolder.online/

No responses yet

Write a response