blogs.huzi.pk
Back to all posts
Programming

10 JavaScript Tricks That Will Save You Hours of Coding Headaches

By Huzi
10 JavaScript Tricks That Will Save You Hours of Coding Headaches

JavaScript is full of hidden gems that can transform verbose code into elegant solutions. After years of working with JS across production applications, I've curated these battle-tested tricks that consistently save development time. Master these and you'll write cleaner, more efficient code immediately.

1. Destructuring with Aliases & Default Values

The Problem: Nested object properties require repetitive null checks.

The Solution:

// Before:
const street = user.address ? user.address.street : 'Unknown';

// After:
const { address: { street: userStreet = 'Unknown' } = {} } = user;

Why it rocks:

  • Aliases (street: userStreet) prevent naming conflicts
  • Default values (= 'Unknown') handle undefined cases
  • Nested destructuring avoids multiple checks

2. Optional Chaining + Nullish Coalescing Combo

The Problem: Endless a && a.b && a.b.c chains for safe access.

The Solution:

// Safely access nested properties
const price = order?.items?.[0]?.price ?? 0;

// Also works with functions:
user.getAddress?.()?.postcode;

Pro Tip: Combine with || for falsy values, but use ?? when 0 or false are valid:

const discount = cart?.discount ?? 15; // 0 won't be overridden

3. Dynamic Object Keys with Computed Properties

The Problem: Creating objects with dynamic keys requires temporary variables.

The Solution:

const key = 'mobile';
const phoneTypes = {
  [key]: 'iPhone',
  [`${key}Model`]: '15 Pro' // Computed key names
};
// { mobile: 'iPhone', mobileModel: '15 Pro' }

Use Case: API response normalization where keys depend on data.

4. Array Filtering Truthy Values

The Problem: Removing null, undefined, 0, '' from arrays manually.

The Solution:

const data = [0, 1, '', 'text', null, undefined];
const clean = data.filter(Boolean); // [1, 'text']

How it works: The Boolean constructor acts as the predicate function.

5. Object Cloning with StructuredClone

The Problem: JSON.parse(JSON.stringify()) fails with Dates, Sets, Maps, and functions.

The Solution:

const deepCopy = structuredClone(original);

// Handles:
// - Date objects
// - Map/Set
// - Circular references

Browser Support: All modern browsers (Node.js 17+)

6. Short-circuit Function Execution

The Problem: Conditional function calls create extra code branches.

The Solution:

// Instead of:
if (isLoggedIn) { fetchData(); }

// Do:
isLoggedIn && fetchData();

// Set defaults:
const apiUrl = env.API_URL || 'https://default.api';

Warning: Avoid for critical logic where clarity is more important. Use traditional conditionals there.

7. Array Deduplication in One Line

The Problem: Removing duplicates with complex loops or external libraries.

The Solution:

const dupes = [1, 2, 2, 3, 4, 4];
const unique = [...new Set(dupes)]; // [1, 2, 3, 4]

// For objects based on a key:
const objSet = [...new Map(users.map(u => [u.id, u])).values()];

8. Function Parameter Destructuring

The Problem: Long, hard-to-read parameter lists with optional configs.

The Solution:

// Before:
function connect(host, port, timeout=10, retries=3) { /*...*/ }

// After:
function connect({ host, port, timeout = 10, retries = 3 }) {
  console.log(`Connecting to ${host}:${port}`);
}

// Usage:
connect({ port: 8080, host: 'api.com' });

Benefits:

  • Self-documenting parameters
  • Order independence
  • Clear default values for missing props

9. Console Debugging Superpowers

The Problem: Basic console.log provides minimal context and clutters your view.

Advanced Tactics:

// 1. Table formatting for objects/arrays:
console.table(users.filter(u => u.active));

// 2. Style debug messages for visibility:
console.log('%cPayment Successful!', 'color: green; font-weight: bold; font-size: 16px;');

// 3. Performance measurement:
console.time('render');
renderComponent();
console.timeEnd('render'); // logs execution time

// 4. Stack traces for debugging call order:
console.trace('Function called from:');

10. URL Parameter Parsing

The Problem: Manually parsing query strings with regex or split().

The Solution:

const params = new URLSearchParams(window.location.search);

// Get single param
const id = params.get('id');

// Convert to object:
const queryObj = Object.fromEntries(params.entries());

// Update params and URL without reloading:
params.set('page', 2);
history.replaceState(null, '', `?${params.toString()}`);

Bonus: Modern Error Handling

The Problem: Nested try/catch hell or unhandled promise rejections.

The Solution:

// 1. Promise error handling with grace:
const data = await fetchData().catch(error => {
  logError(error);
  return fallbackData; // Return a default value to prevent app crash
});

// 2. Error boundary pattern (React):
function ErrorBoundary({ children }) {
  try {
    return children;
  } catch (error) {
    return <FallbackUI error={error} />;
  }
}

When NOT to Use These Tricks

While powerful, avoid these patterns when they harm readability:

  • Short-circuiting for critical logic: An explicit if statement is always clearer for business rules.
  • Overly nested optional chaining: If data is missing deep in a structure, it might indicate a bigger problem that shouldn't be silenced.
  • "Clever" one-liners: If team members aren't familiar with a pattern, a more verbose but understandable version is better.

"The art of writing code is knowing when not to be clever."

Level Up Your Workflow

Implement these immediately:

  1. Replace all deep-access null checks with ?. and ??.
  2. Refactor any function with more than 3 parameters to use object destructuring.
  3. Use console.table() for your next array debugging session. You'll never go back.

Comments (0)

No comments yet. Be the first to share your thoughts!


Leave a Comment