Skip to content

Latest commit

 

History

History
204 lines (190 loc) · 6.27 KB

File metadata and controls

204 lines (190 loc) · 6.27 KB
description Vibe coding guidelines and architectural constraints for Modern JavaScript Syntax & FP within the frontend domain.
technology JavaScript
domain frontend
level Senior/Architect
version ES2024+
tags
javascript
es6
functional-programming
best-practices
clean-code
scalable-code
ai_role Senior JavaScript Expert
last_updated 2026-03-22

✨ Modern JavaScript Syntax & Functional Programming Best Practices

📖 Context & Scope

  • Primary Goal: Enforce strict adherence to modern ES6+ syntax and functional programming patterns.
  • Target Tooling: Cursor, Windsurf, Antigravity.
  • Tech Stack Version: ES2024+

II. Modern Syntax & FP (ES6-ES2024)

11. Manual object property assignment vs Shorthand

Context: Reducing boilerplate in object creation.

❌ Bad Practice

const name = 'Alice';
const user = {
    name: name,
    age: age
};

⚠️ Problem

Redundant repetition of keys and values increases file size and makes the code noisier.

✅ Best Practice

const name = 'Alice';
const user = { name, age };

🚀 Solution

Use Property Shorthand. When the key and variable name match, omit the value.

12. Using arguments vs Rest parameters

Context: Handling variable numbers of arguments.

❌ Bad Practice

function sum() {
    const args = Array.prototype.slice.call(arguments);
    return args.reduce((a, b) => a + b);
}

⚠️ Problem

The arguments object is not a real array (it lacks methods like map or reduce). It is also incompatible with arrow functions and optimization in some V8 versions.

✅ Best Practice

const sum = (...args) => args.reduce((a, b) => a + b);

🚀 Solution

Use Rest Parameters (...args). They create a real array and are more explicit about the function's intent.

13. Manual array copying vs Spread

Context: Immutability and array manipulation.

❌ Bad Practice

const original = [1, 2, 3];
const copy = [];
for (let i = 0; i < original.length; i++) {
    copy.push(original[i]);
}

⚠️ Problem

Manual loops for copying are verbose and imperative. They increase the surface area for bugs (off-by-one errors).

✅ Best Practice

const original = [1, 2, 3];
const copy = [...original];

🚀 Solution

Use the Spread Operator (...). It is concise, declarative, and highly optimized by modern engines.

14. Nested Destructuring

Context: Extracting data from complex objects.

❌ Bad Practice

const city = user.location.address.city;
const zip = user.location.address.zip;

⚠️ Problem

Repetitive property access is verbose and risks "cannot read property of undefined" errors if any parent object is missing.

✅ Best Practice

const { location: { address: { city, zip } } } = user;

🚀 Solution

Use nested destructuring to extract deeply nested values in a single statement. (Note: Combine with optional chaining if path existence isn't guaranteed).

15. Default Parameters

Context: Handling missing arguments.

❌ Bad Practice

function setRole(role) {
    role = role || 'guest';
    // ...
}

⚠️ Problem

Using || for defaults is dangerous if the argument is a "falsy" but valid value (like 0, false, or '').

✅ Best Practice

function setRole(role = 'guest') {
    // ...
}

🚀 Solution

Use ES6 Default Parameters. They only apply if the argument is undefined.

16. forEach for data transformation vs map/filter

Context: Declarative vs Imperative programming.

❌ Bad Practice

const double = [];
numbers.forEach(n => {
    double.push(n * 2);
});

⚠️ Problem

forEach relies on side effects (mutating an outer array). It is less expressive and harder to chain than functional alternatives.

✅ Best Practice

const double = numbers.map(n => n * 2);

🚀 Solution

Use map, filter, and reduce for data transformations. They return new arrays and promote immutability.

17. Object mutation vs Immutability

Context: State management and predictability.

❌ Bad Practice

function updateAge(user) {
    user.age = 30; // Mutates original object
    return user;
}

⚠️ Problem

Mutating objects passed by reference can lead to side effects in other parts of the application that share the same reference, making debugging a nightmare.

✅ Best Practice

const updateAge = (user) => ({ ...user, age: 30 });

🚀 Solution

Treat objects as immutable. Use the spread operator to create copies with updated properties.

18. Switch statements vs Object Literals

Context: Simplifying conditional branching.

❌ Bad Practice

switch (action) {
    case 'CREATE': return doCreate();
    case 'UPDATE': return doUpdate();
    default: return doNothing();
}

⚠️ Problem

switch statements are verbose, require break to prevent fallthrough bugs, and have a non-standard block scope.

✅ Best Practice

const actions = {
    CREATE: doCreate,
    UPDATE: doUpdate
};
return (actions[action] || doNothing)();

🚀 Solution

Use an Object Literal (or Map) as a lookup table. It is cleaner, faster, and more extensible.

19. Not using Optional Chaining ?.

Context: Safe property access in nested objects.

❌ Bad Practice

const street = user && user.address && user.address.street;

⚠️ Problem

The "logical AND" chain is verbose and repetitive. It quickly becomes unreadable with deeper nesting.

✅ Best Practice

const street = user?.address?.street;

🚀 Solution

Use Optional Chaining (?.). It short-circuits to undefined if any part of the chain is nullish.

20. Not using Nullish Coalescing ??

Context: Providing fallback values safely.

❌ Bad Practice

const timeout = config.timeout || 5000;

⚠️ Problem

If config.timeout is 0, the code will incorrectly fall back to 5000 because 0 is falsy.

✅ Best Practice

const timeout = config.timeout ?? 5000;

🚀 Solution

Use Nullish Coalescing (??). It only falls back if the value is null or undefined, allowing 0, false, and '' to be valid.