VOOZH about

URL: https://dev.to/lucasmdevdev/15-javascript-tips-that-will-make-you-a-better-developer-in-2026-28pl

⇱ 15 JavaScript Tips That Will Make You a Better Developer in 2026 - DEV Community


These JavaScript tips have genuinely improved my code quality. No fluff — just patterns that work.

1. Optional Chaining is Your Best Friend

// Old way - ugly and error-prone
const city = user && user.address && user.address.city;

// Modern way
const city = user?.address?.city;

// With methods
const first = arr?.at(0);
const len = str?.trim()?.length;

2. Nullish Coalescing vs OR

// || uses any falsy value (0, '', false are falsy!)
const count = data.count || 10; // BUG: returns 10 when count is 0

// ?? only triggers on null/undefined
const count = data.count ?? 10; // CORRECT: returns 0 when count is 0

3. Object Destructuring with Defaults

function createUser({ 
 name, 
 role = 'user', 
 active = true,
 theme = 'light'
} = {}) {
 return { name, role, active, theme };
}

// The = {} default allows calling with no arguments
createUser(); // Works!
createUser({ name: 'Alice' }); // { name: 'Alice', role: 'user', active: true, theme: 'light' }

4. Array Methods Over Loops

const users = [
 { name: 'Alice', age: 25, active: true },
 { name: 'Bob', age: 30, active: false },
 { name: 'Charlie', age: 22, active: true }
];

// Get names of active users over 24, sorted alphabetically
const result = users
 .filter(u => u.active && u.age > 24)
 .map(u => u.name)
 .sort();

// Result: ['Alice']

5. Promise.allSettled for Parallel Requests

// Promise.all fails if ANY request fails
// Promise.allSettled waits for all, reports success/failure for each

const results = await Promise.allSettled([
 fetch('/api/users'),
 fetch('/api/posts'),
 fetch('/api/comments')
]);

results.forEach((result, index) => {
 if (result.status === 'fulfilled') {
 console.log(`Request ${index}: success`);
 } else {
 console.log(`Request ${index}: failed - ${result.reason}`);
 }
});

6. WeakMap for Private Data

const privateData = new WeakMap();

class User {
 constructor(name, password) {
 privateData.set(this, { password });
 this.name = name;
 }

 checkPassword(input) {
 return privateData.get(this).password === input;
 }
}

const user = new User('Alice', 'secret123');
console.log(user.checkPassword('secret123')); // true
console.log(user.password); // undefined - truly private!

7. Object.fromEntries for Transformations

const prices = { apple: 1.5, banana: 0.5, cherry: 3.0 };

// Apply 10% discount to all
const discounted = Object.fromEntries(
 Object.entries(prices).map(([key, value]) => [key, value * 0.9])
);

// { apple: 1.35, banana: 0.45, cherry: 2.7 }

8. Logical Assignment Operators

// ||= assigns only if left side is falsy
user.role ||= 'guest';

// &&= assigns only if left side is truthy
user.profile &&= updateProfile(user.profile);

// ??= assigns only if left side is null/undefined
config.timeout ??= 3000;

9. Array.at() for Negative Indexing

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

// Old way
const last = arr[arr.length - 1]; // 5

// Modern way
const last = arr.at(-1); // 5
const secondLast = arr.at(-2); // 4

10. Structured Clone for Deep Copy

// JSON.parse(JSON.stringify()) breaks dates, functions, etc.
const shallow = { ...obj }; // Shallow copy only

// Proper deep clone (Node 17+, all modern browsers)
const deep = structuredClone(obj);

11. AbortController for Request Cancellation

async function fetchWithTimeout(url, timeout = 5000) {
 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), timeout);

 try {
 const response = await fetch(url, { signal: controller.signal });
 clearTimeout(timeoutId);
 return response.json();
 } catch (err) {
 if (err.name === 'AbortError') {
 throw new Error('Request timed out');
 }
 throw err;
 }
}

12. Generator Functions for Lazy Sequences

function* fibonacci() {
 let [a, b] = [0, 1];
 while (true) {
 yield a;
 [a, b] = [b, a + b];
 }
}

const fib = fibonacci();
const first10 = Array.from({ length: 10 }, () => fib.next().value);
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

13. Error Cause for Better Debugging

async function fetchUser(id) {
 try {
 const data = await db.query('SELECT * FROM users WHERE id = ?', [id]);
 return data;
 } catch (err) {
 throw new Error(`Failed to fetch user ${id}`, { cause: err });
 }
}

// Now you can access the original error
try {
 await fetchUser(42);
} catch (err) {
 console.log(err.message); // "Failed to fetch user 42"
 console.log(err.cause); // Original DB error
}

14. Array Grouping with Object.groupBy

const inventory = [
 { name: 'asparagus', type: 'vegetables', quantity: 5 },
 { name: 'bananas', type: 'fruit', quantity: 0 },
 { name: 'cherries', type: 'fruit', quantity: 2 },
 { name: 'carrots', type: 'vegetables', quantity: 1 },
];

const grouped = Object.groupBy(inventory, ({ type }) => type);
// {
// vegetables: [asparagus, carrots],
// fruit: [bananas, cherries]
// }

15. Using console Better

// Group related logs
console.group('User Authentication');
console.log('Checking credentials...');
console.log('Token validated');
console.groupEnd();

// Time operations
console.time('db-query');
await db.query('...');
console.timeEnd('db-query'); // db-query: 23.4ms

// Table for arrays/objects
console.table(users);

// Assert (throws if false)
console.assert(user.id > 0, 'User ID must be positive');

Key Takeaways

  • Use ?. and ?? instead of manual null checks
  • Prefer Promise.allSettled when you need all results
  • Use structuredClone for deep copies
  • Embrace new syntax — it's in all modern browsers

Which of these was new to you? Let me know in the comments!


Follow me for weekly JavaScript and web dev tips.