From b50ebd8b89380bf2a63eb11dce71039749ba2b8a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 17:39:01 +0000 Subject: [PATCH] style(ui): autonomous visual optimization of readme files and security rules Co-authored-by: beginwebdev2002 <102213457+beginwebdev2002@users.noreply.github.com> --- .jules/rules/security.md | 2 +- frontend/angular/readme.md | 651 +--------------------------------- frontend/javascript/readme.md | 589 ------------------------------ 3 files changed, 2 insertions(+), 1240 deletions(-) diff --git a/.jules/rules/security.md b/.jules/rules/security.md index a72b718..97a7644 100644 --- a/.jules/rules/security.md +++ b/.jules/rules/security.md @@ -60,7 +60,7 @@ graph TD ``` -| Security Layer | Pattern/Standard | Jules Requirement | +| 🛡️ Security Layer | 🧩 Pattern/Standard | 🤖 Jules Requirement | | :--- | :--- | :--- | | **Transport** | TLS / HTTPS | Ensure all intra-service and external communication is encrypted (HTTPS only). | | **API Defense** | Rate Limiting | Add middleware to block brute-force and DDoS attempts per IP/User. | diff --git a/frontend/angular/readme.md b/frontend/angular/readme.md index ec075d5..a877b31 100644 --- a/frontend/angular/readme.md +++ b/frontend/angular/readme.md @@ -9,15 +9,9 @@ ai_role: Senior Angular Performance Expert last_updated: 2026-03-22 --- -<<<<<<< feat/autonomous-vibe-coding-docs-10177351143416239543 -# 🅰️ Angular Best Practices & Production-Ready Patterns - -## 🎯 Context & Scope -======= # 🎨 Angular Best Practices & Production-Ready Patterns -# 🎨 Context & Scope ->>>>>>> main +## 🎯 Context & Scope - **Primary Goal:** Enforce strict adherence to modern Angular v20 patterns, specifically Zoneless reactivity and functional APIs for optimal best practices. - **Target Tooling:** Cursor, Windsurf, Antigravity. - **Tech Stack Version:** Angular 20 @@ -296,648 +290,6 @@ Migrate to Zoneless mode. Use Signals to notify Angular when a re-render is need --- -<<<<<<< feat/autonomous-vibe-coding-docs-10177351143416239543 ---- -[⬆️ Back to Top](#) - -## II. Architecture & DI (16-30) - -### 🚨 16. Services provided in 'root' vs Modules -**Context:** Tree Shaking -#### ❌ Bad Practice -```typescript -@NgModule({ providers: [MyService] }) -``` -#### ⚠️ Problem -The service is included in the bundle even if it is not used. -#### ✅ Best Practice -```typescript -@Injectable({ providedIn: 'root' }) -``` -#### 🚀 Solution -Always use `providedIn: 'root'`. This allows the bundler to remove unused services (Tree Shaking). - -### 🚨 17. Class-based Guards -**Context:** Routing Security -#### ❌ Bad Practice -```typescript -@Injectable() -export class AuthGuard implements CanActivate { ... } -``` -#### ⚠️ Problem -Class-based guards require more code and injections. They are less flexible for composition. -#### ✅ Best Practice -```typescript -export const authGuard: CanActivateFn = (route, state) => { - return inject(AuthService).isLoggedIn(); -}; -``` -#### 🚀 Solution -Use functional Guards (`CanActivateFn`). They are concise, easy to test, and composable. - -### 🚨 18. Class-based Interceptors -**Context:** HTTP Requests -#### ❌ Bad Practice -```typescript -@Injectable() -export class TokenInterceptor implements HttpInterceptor { ... } -``` -#### ⚠️ Problem -Similar to guards: lots of boilerplate, complex registration in the providers array. -#### ✅ Best Practice -```typescript -export const tokenInterceptor: HttpInterceptorFn = (req, next) => { - const token = inject(AuthService).token(); - return next(req.clone({ setHeaders: { Authorization: token } })); -}; -``` -#### 🚀 Solution -Use functional Interceptors (`HttpInterceptorFn`) with `provideHttpClient(withInterceptors([...]))`. - -### 🚨 19. State Mutation in Services -**Context:** Data Integrity -#### ❌ Bad Practice -```typescript -updateUser(user: User) { - this.currentUser = user; // Mutable assignment -} -``` -#### ⚠️ Problem -Object mutations complicate change tracking and can lead to unpredictable behavior in components using the `OnPush` strategy. -#### ✅ Best Practice -```typescript -currentUser = signal(null); -updateUser(user: User) { - this.currentUser.set({ ...user }); // Immutable update -} -``` -#### 🚀 Solution -Use Signals for state management. They guarantee reactivity and atomicity of updates. - -### 🚨 20. Calling functions inside `@for` tracking -**Context:** Rendering Performance -#### ❌ Bad Practice -```html -@for (item of items; track getItemId(item)) -``` -#### ⚠️ Problem -The tracking function is called for each element during every re-render. -#### ✅ Best Practice -```html -@for (item of items; track item.id) -``` -#### 🚀 Solution -Use an object property (ID or a unique key) directly. If a function is needed, it must be as simple and pure as possible. - -### 🚨 21. `host` property vs `@HostListener` -**Context:** Component Metadata -#### ❌ Bad Practice -```typescript -@HostListener('click') onClick() { ... } -@HostBinding('class.active') isActive = true; -``` -#### ⚠️ Problem -Decorators increase class size and scatter host configuration across the file. -#### ✅ Best Practice -```typescript -@Component({ - host: { - '(click)': 'onClick()', - '[class.active]': 'isActive()' - } -}) -``` -#### 🚀 Solution -Use the `host` property in component metadata. This centralizes all host element settings. - -### 🚨 22. Dynamic Components with `ComponentFactoryResolver` -**Context:** Dynamic Rendering -#### ❌ Bad Practice -```typescript -const factory = this.resolver.resolveComponentFactory(MyComponent); -this.container.createComponent(factory); -``` -#### ⚠️ Problem -`ComponentFactoryResolver` is deprecated. It is an old imperative API. -#### ✅ Best Practice -```typescript -this.container.createComponent(MyComponent); -// Or strictly in template - -``` -#### 🚀 Solution -Use `ViewContainerRef.createComponent` directly with the component class or the `ngComponentOutlet` directive. - -### 🚨 23. Shared Modules (The "Dump" Module) -**Context:** Modular Architecture -#### ❌ Bad Practice -`SharedModule` imports and exports *all* UI components, pipes, and directives. -#### ⚠️ Problem -If a component needs a single button, it is forced to pull the entire `SharedModule`. This breaks Tree Shaking and increases the initial bundle size. -#### ✅ Best Practice -Import only what is needed directly into the `imports` of the Standalone component. -#### 🚀 Solution -Abandon `SharedModule` in favor of granular imports of Standalone entities. - -### 🚨 24. Circular Dependencies in DI -**Context:** Architecture -#### ❌ Bad Practice -Service A injects Service B, which injects Service A. -#### ⚠️ Problem -Leads to runtime errors ("Cannot instantiate cyclic dependency"). Indicates poor architectural design. -#### ✅ Best Practice -Use `forwardRef()` as a crutch, but it's better to extract the shared logic into a third Service C. -#### 🚀 Solution -Refactoring: break services into smaller ones following SRP (Single Responsibility Principle). - -### 🚨 25. Logic in Pipes -**Context:** Separation of Concerns -#### ❌ Bad Practice -A Pipe performs HTTP requests or complex business logic. -#### ⚠️ Problem -Pipes are intended for data transformation in the template. Side effects in pipes violate function purity and kill CD performance. -#### ✅ Best Practice -Pipes should be "Pure" (without side effects) and fast. -#### 🚀 Solution -Extract logic into services/signals. Leave only formatting to pipes. - -### 🚨 26. `any` in Services -**Context:** TypeScript Safety -#### ❌ Bad Practice -```typescript -getData(): Observable { ... } -``` -#### ⚠️ Problem -`any` disables type checking, nullifying the benefits of TypeScript. Errors only surface at runtime. -#### ✅ Best Practice -```typescript -getData(): Observable { ... } -``` -#### 🚀 Solution -Use DTO interfaces (generate them from Swagger/OpenAPI) and Zod for API response validation. - -### 🚨 27. Multiple `async` pipes for same stream -**Context:** RxJS Subscriptions -#### ❌ Bad Practice -```html -
{{ (user$ | async).name }}
-``` -#### ⚠️ Problem -Each `async` pipe creates a new subscription. This can lead to duplicated HTTP requests. -#### ✅ Best Practice -```html -@if (user$ | async; as user) { -
{{ user.name }}
-} -``` -#### 🚀 Solution -Use aliases in the template (`as varName`) or convert the stream to a signal (`toSignal`). - -### 🚨 28. ProvidedIn 'any' -**Context:** DI Scopes -#### ❌ Bad Practice -```typescript -@Injectable({ providedIn: 'any' }) -``` -#### ⚠️ Problem -Creates a new service instance for each lazy-loaded module. This is often unexpected behavior, leading to state desynchronization (different singleton instances). -#### ✅ Best Practice -`providedIn: 'root'` or providing at the level of a specific component (`providers: []`). -#### 🚀 Solution -Avoid `any`. Explicitly control the scope: either global (`root`) or local. - -### 🚨 29. Imperative Routing -**Context:** Navigation -#### ❌ Bad Practice -```typescript -this.router.navigateByUrl('/users/' + id); -``` -#### ⚠️ Problem -Hardcoding route strings makes route refactoring a pain. -#### ✅ Best Practice -```typescript -this.router.navigate(['users', id]); -``` -#### 🚀 Solution -Use an array of segments. It is safer (automatic encoding of URL parameters) and cleaner. - -### 🚨 30. Ignoring `OnPush` Strategy -**Context:** Change Detection Strategy -#### ❌ Bad Practice -Default components (`ChangeDetectionStrategy.Default`). -#### ⚠️ Problem -Angular checks this component on *every* app event, even if the component data hasn't changed. -#### ✅ Best Practice -```typescript -changeDetection: ChangeDetectionStrategy.OnPush -``` -#### 🚀 Solution -Always set `OnPush`. With signals, this becomes the de facto standard, as updates occur precisely. - ---- - ---- -[⬆️ Back to Top](#) - -## III. Advanced Performance (31-45) - -### 🚨 31. Eager Loading of Heavy Components -**Context:** Bundle Size -#### ❌ Bad Practice -```html - -``` -#### ⚠️ Problem -A charting library (e.g., ECharts) loads immediately, blocking TTI (Time to Interactive), even if the chart is below the "fold". -#### ✅ Best Practice -```html -@defer (on viewport) { - -} @placeholder { -
Loading chart...
-} -``` -#### 🚀 Solution -Use `@defer`. This defers component code loading until a trigger occurs (viewport, interaction, timer). - -### 🚨 32. Heavy Computation in Main Thread -**Context:** Event Loop Blocking -#### ❌ Bad Practice -Sorting an array of 100k elements directly in the component. -#### ⚠️ Problem -Freezes the UI. -#### ✅ Best Practice -Offload computations to a Web Worker. -#### 🚀 Solution -Use Angular Web Workers. In v20, this is easily configured via the CLI. - -### 🚨 33. Memory Leaks in `effect()` -**Context:** Signal Effects -#### ❌ Bad Practice -```typescript -effect(() => { - const timer = setInterval(() => ..., 1000); - // No cleanup -}); -``` -#### ⚠️ Problem -Effects restart when dependencies change. If you don't clean up timers/subscriptions inside an effect, they accumulate. -#### ✅ Best Practice -```typescript -effect((onCleanup) => { - const timer = setInterval(() => ..., 1000); - onCleanup(() => clearInterval(timer)); -}); -``` -#### 🚀 Solution -Always use the `onCleanup` callback to release resources. - -### 🚨 34. Excessive Change Detection with `NgZone.run()` -**Context:** Zone Integration -#### ❌ Bad Practice -Wrapping third-party libraries in `ngZone.run()` unnecessarily. -#### ⚠️ Problem -Forces redundant checks of the entire component tree. -#### ✅ Best Practice -```typescript -ngZone.runOutsideAngular(() => { - // Heavy chart rendering or canvas animation -}); -``` -#### 🚀 Solution -Run frequent events (scroll, mousemove, animationFrame) *outside* the Angular zone. Update signals only when UI updates are required. - -### 🚨 35. Signals equality check default -**Context:** Signal Performance -#### ❌ Bad Practice -```typescript -data = signal({ id: 1 }, { equal: undefined }); // Default checks reference -``` -#### ⚠️ Problem -If you create a new object with the same data `{ id: 1 }`, the signal triggers an update, even though the data hasn't fundamentally changed. -#### ✅ Best Practice -```typescript -import { isEqual } from 'lodash-es'; -data = signal(obj, { equal: isEqual }); -``` -#### 🚀 Solution -Use a custom comparison function for complex objects to avoid redundant re-renders. - -### 🚨 36. Lacking `trackBy` in iterables -**Context:** Re-rendering Lists -#### ❌ Bad Practice -```html -
  • {{ item }}
  • -``` -#### ⚠️ Problem -Without tracking, any array change leads to the recreation of all DOM nodes in the list. $O(n)$ DOM operations. -#### ✅ Best Practice -```html -@for (item of items; track item.id) -``` -#### 🚀 Solution -Always use a unique key in `track`. This allows Angular to move DOM nodes instead of recreating them. - -### 🚨 37. Recursive Template without Caching -**Context:** Tree Rendering -#### ❌ Bad Practice -Recursive component call without `OnPush` and memoization. -#### ⚠️ Problem -Exponential growth in change detection checks. -#### ✅ Best Practice -Using the `Memoization` pattern or `computed()` to prepare the tree data structure. - -### 🚨 38. Global Styles Leakage -**Context:** CSS Encapsulation -#### ❌ Bad Practice -```css -/* global.css */ -button { padding: 10px; } -``` -#### ⚠️ Problem -Global styles unpredictably affect components. -#### ✅ Best Practice -Use `ViewEncapsulation.Emulated` (default) and specific selectors. -#### 🚀 Solution -Keep styles locally within components. - -### 🚨 39. Large Component Bundle -**Context:** Split Chunks -#### ❌ Bad Practice -A single huge component of 3000 lines. -#### ⚠️ Problem -Poor readability, rendering lazy loading of UI parts impossible. -#### ✅ Best Practice -Decompose into "dumb" (UI) and "smart" components. -#### 🚀 Solution -Break down the UI into small, reusable blocks. - -### 🚨 40. Image Optimization Ignorance -**Context:** Core Web Vitals (LCP) -#### ❌ Bad Practice -```html - -``` -#### ⚠️ Problem -The browser loads the full image, shifting the layout (CLS). -#### ✅ Best Practice -```html - -``` -#### 🚀 Solution -Use the `NgOptimizedImage` directive. It automatically handles lazy loading, preconnect, and srcset. - -### 🚨 41. Hydration Mismatch -**Context:** SSR / SSG -#### ❌ Bad Practice -Rendering `Date.now()` or random numbers (`Math.random()`) directly in the template. -#### ⚠️ Problem -The server generates one number, the client another. This causes "flickering" and a hydration error; Angular discards the server DOM and renders from scratch. -#### ✅ Best Practice -Use stable data or defer random generation until `afterNextRender`. -#### 🚀 Solution -Pay attention to template determinism with SSR. - -### 🚨 42. Synchronous `inject()` inside loops -**Context:** DI Performance -#### ❌ Bad Practice -Calling `inject()` inside a function that loops. -#### ⚠️ Problem -Although `inject` is fast, in hot paths these are unnecessary DI tree lookups. -#### ✅ Best Practice -Inject dependency once at the class/file constant level. - -### 🚨 43. Unused Signal Dependencies -**Context:** Signal Graph -#### ❌ Bad Practice -Reading a signal inside `computed` whose value doesn't affect the result (an unexecuted logical branch). -#### ⚠️ Problem -Angular dynamically builds the dependency graph. If you accidentally read a signal, it becomes a dependency. -#### ✅ Best Practice -Use `untracked()` to read signals whose changes should not trigger a recalculation. - -### 🚨 44. Excessive Wrappers (`div` soup) -**Context:** DOM Size -#### ❌ Bad Practice -```html -
    -``` -#### ⚠️ Problem -Increases DOM tree depth, slowing down Style Recalculation and Layout. -#### ✅ Best Practice -Use `` to group elements without creating extra DOM nodes. - -### 🚨 45. Neglecting `runOutsideAngular` for Events -**Context:** High-frequency events -#### ❌ Bad Practice -`@HostListener('window:scroll')` -#### ⚠️ Problem -Every scroll event triggers Change Detection. -#### ✅ Best Practice -Subscribe manually in `runOutsideAngular` and update the signal only when necessary. - ---- - ---- -[⬆️ Back to Top](#) - -## IV. Data & Forms (46-55) - -### 🚨 46. Template-Driven Forms without Types -**Context:** Form Safety -#### ❌ Bad Practice -`[(ngModel)]` without strict model typing. -#### ⚠️ Problem -Risk of assigning a string to a numeric field. -#### ✅ Best Practice -Use Reactive Forms with `FormControl` typing or new Signal-based Forms (when out of developer preview). - -### 🚨 47. Untyped `FormGroup` -**Context:** Reactive Forms -#### ❌ Bad Practice -```typescript -const form = new FormGroup({ ... }); // Untyped -``` -#### ⚠️ Problem -`form.value` returns `any`. -#### ✅ Best Practice -```typescript -const form = new FormGroup({ - email: new FormControl('', { nonNullable: true }), - ... -}); -``` -#### 🚀 Solution -Always type forms. Use `nonNullable: true` to avoid `string | undefined` hell. - -### 🚨 48. Subscribe inside Subscribe -**Context:** RxJS Patterns -#### ❌ Bad Practice -```typescript -this.route.params.subscribe(params => { - this.api.getUser(params.id).subscribe(user => ...); -}); -``` -#### ⚠️ Problem -Classic Race Condition. If parameters change rapidly, response order is not guaranteed. -#### ✅ Best Practice -```typescript -this.route.params.pipe( - switchMap(params => this.api.getUser(params.id)) -).subscribe(); -``` -#### 🚀 Solution -Use Flattening Operators (`switchMap`, `concatMap`, `mergeMap`). - -### 🚨 49. Ignoring `AbortSignal` in HTTP -**Context:** Network Efficiency -#### ❌ Bad Practice -Ignoring request cancellation when navigating away from the page. -#### ⚠️ Problem -Requests continue hanging, consuming traffic. -#### ✅ Best Practice -HttpClient automatically supports cancellation upon unsubscription. With signals: ensure `rxResource` or the effect correctly cancels the request. - -### 🚨 50. Mutating Inputs directly -**Context:** Unidirectional Data Flow -#### ❌ Bad Practice -```typescript -this.inputData.push(newItem); -``` -#### ⚠️ Problem -The parent component remains unaware of the change. Violates the One-Way Data Flow principle. -#### ✅ Best Practice -Emit event (`output`) upwards; the parent changes the data and passes the new object downwards. - -### 🚨 51. `ngModel` inside Reactive Form -**Context:** Form Mixing -#### ❌ Bad Practice -Using `formControlName` and `[(ngModel)]` on the same input. -#### ⚠️ Problem -Deprecated behavior. Causes form and model synchronization conflicts. -#### ✅ Best Practice -Use only one approach: either Reactive or Template-driven. - -### 🚨 52. Complex Validators in Template -**Context:** Form Logic -#### ❌ Bad Practice -Validation via HTML attributes for complex logic. -#### ⚠️ Problem -Hard to test, no reusability. -#### ✅ Best Practice -Custom Validator Functions or Async Validators in the component class. - -### 🚨 53. Forgetting `updateOn: 'blur'` -**Context:** Performance -#### ❌ Bad Practice -Validating a complex field on every keystroke (`change`). -#### ⚠️ Problem -Slows down user input. -#### ✅ Best Practice -```typescript -new FormControl('', { updateOn: 'blur' }); -``` -#### 🚀 Solution -Trigger validation/update only when the user has finished typing. - -### 🚨 54. Not handling API Errors -**Context:** UX -#### ❌ Bad Practice -`.subscribe(data => ...)` without an error callback. -#### ⚠️ Problem -On a 500 error, the application "hangs" in a loading state. -#### ✅ Best Practice -Global Error Handler or `catchError` in the pipe returning a safe value. - -### 🚨 55. Hardcoded API URLs -**Context:** Maintainability -#### ❌ Bad Practice -`http.get('https://api.com/users')` -#### ⚠️ Problem -Inability to switch environments (dev/prod). -#### ✅ Best Practice -Using InjectionToken `API_URL` and environment configuration. - ---- - ---- -[⬆️ Back to Top](#) - -## V. Expert/Niche (56-60) - -### 🚨 56. `untracked()` usage -**Context:** Fine-grained Reactivity -#### ❌ Bad Practice -Accidentally creating a cyclic dependency in `computed`. -#### ⚠️ Problem -`Error: Detected cycle in computations`. -#### ✅ Best Practice -```typescript -computed(() => { - const user = this.user(); - untracked(() => this.logger.log(user)); // Logging doesn't create dependency - return user.name; -}); -``` -#### 🚀 Solution -Use `untracked()` for side effects or reads that shouldn't affect recalculation. - -### 🚨 57. V8 Hidden Classes Optimization -**Context:** Micro-optimization -#### ❌ Bad Practice -```typescript -user = signal({}); -// later -user.set({ name: 'A', age: 10 }); // Shape change -``` -#### ⚠️ Problem -Initializing with an empty object and later adding fields changes the object "shape" (Hidden Class), breaking V8 JIT compiler optimization. -#### ✅ Best Practice -```typescript -interface User { name: string | null; age: number | null; } -user = signal({ name: null, age: null }); -``` -#### 🚀 Solution -Always initialize signals with the full object shape (even with null) to preserve property access monomorphism. - -### 🚨 58. Signal Glitch Freedom abuse -**Context:** Reactivity Theory -#### ❌ Bad Practice -Relying on `effect` to fire synchronously. -#### ⚠️ Problem -Signals guarantee "Glitch Freedom" (absence of intermediate inconsistent states), but effects are asynchronous (microtask timing). -#### ✅ Best Practice -Do not use effects to synchronize local state. Use `computed`. - -### 🚨 59. Memory leaks in `root` Effects -**Context:** Application Lifecycle -#### ❌ Bad Practice -Creating an effect in a service without `manualCleanup`. -#### ⚠️ Problem -Effects in `root` services live forever. If they subscribe to something global, it can leak. -#### ✅ Best Practice -Usually fine, but if the service is destroyed (rare lazy loading case), the effect must be cleaned up with `effectRef.destroy()`. - -### 🚨 60. `runInInjectionContext` -**Context:** Advanced DI -#### ❌ Bad Practice -Passing an `Injector` instance manually into functions. -#### ⚠️ Problem -Bulky code. -#### ✅ Best Practice -```typescript -runInInjectionContext(this.injector, () => { - // can use inject() here dynamically - const service = inject(MyService); -}); -``` -#### 🚀 Solution -Use this helper to execute functions requiring a DI context outside the constructor/initialization. - ---- -[⬆️ Back to Top](#) -======= - ## 📚 Specialized Topics For further reading, please refer to the following specialized guides: @@ -946,4 +298,3 @@ For further reading, please refer to the following specialized guides: - [🚀 Advanced Performance](./advanced-performance.md) - [📝 Data & Forms](./data-forms.md) - [🧠 Expert/Niche Topics](./expert-niche.md) ->>>>>>> main diff --git a/frontend/javascript/readme.md b/frontend/javascript/readme.md index 74bf3b4..d512c4e 100644 --- a/frontend/javascript/readme.md +++ b/frontend/javascript/readme.md @@ -226,594 +226,6 @@ Use descriptive, camelCase names that convey the intent and data type of the var --- -<<<<<<< feat/autonomous-vibe-coding-docs-10177351143416239543 ---- -[⬆️ Back to Top](#) - -## II. Modern Syntax & FP (ES6-ES2024) - -### 🚨 11. Manual object property assignment vs Shorthand -**Context:** Reducing boilerplate in object creation. -#### ❌ Bad Practice -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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 -```javascript -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. - ---- - ---- -[⬆️ Back to Top](#) - -## III. Asynchronous & Logic - -### 🚨 21. Callback Hell vs Promises -**Context:** Managing asynchronous execution flow. -#### ❌ Bad Practice -```javascript -getData(url, (err, res) => { - getDetails(res.id, (err, details) => { - saveData(details, (err, ok) => { - // Callback Hell - }); - }); -}); -``` -#### ⚠️ Problem -Deeply nested callbacks (the "Pyramid of Doom") make error handling extremely difficult and code unreadable. -#### ✅ Best Practice -```javascript -fetchData(url) - .then(res => fetchDetails(res.id)) - .then(details => saveData(details)) - .catch(err => handleError(err)); -``` -#### 🚀 Solution -Use Promises to flatten the structure and centralize error handling with `.catch()`. - -### 🚨 22. Promise.then() nesting vs Async/Await -**Context:** Modern syntax for asynchronous code. -#### ❌ Bad Practice -```javascript -function load() { - return api.get().then(res => { - return api.process(res).then(processed => { - return processed; - }); - }); -} -``` -#### ⚠️ Problem -Even with Promises, `.then()` nesting can occur. It still feels like "callback style" logic. -#### ✅ Best Practice -```javascript -async function load() { - const res = await api.get(); - const processed = await api.process(res); - return processed; -} -``` -#### 🚀 Solution -Use `async/await`. It allows asynchronous code to be written and read like synchronous code, improving maintainability. - -### 🚨 23. Sequential `await` in loops vs `Promise.all` -**Context:** Parallelizing independent asynchronous operations. -#### ❌ Bad Practice -```javascript -for (const id of ids) { - await fetchItem(id); // Pauses loop for each request -} -``` -#### ⚠️ Problem -Sequential `await` in a loop causes a "waterfall" effect, where each request waits for the previous one to finish, significantly increasing total execution time. -#### ✅ Best Practice -```javascript -const promises = ids.map(id => fetchItem(id)); -await Promise.all(promises); -``` -#### 🚀 Solution -Use `Promise.all` to execute independent promises in parallel. This utilizes the full network/IO bandwidth. - -### 🚨 24. Missing `try/catch` in async -**Context:** Handling failures in async functions. -#### ❌ Bad Practice -```javascript -async function getData() { - const data = await fetch(url); // If this fails, the process might crash - return data; -} -``` -#### ⚠️ Problem -Unhandled exceptions in `async` functions result in unhandled promise rejections, which can lead to silent failures or process termination in Node.js. -#### ✅ Best Practice -```javascript -async function getData() { - try { - const data = await fetch(url); - return data; - } catch (error) { - logError(error); - } -} -``` -#### 🚀 Solution -Wrap `await` calls in `try/catch` blocks or use a higher-order function to catch errors. - -### 🚨 25. Floating point math errors (`0.1 + 0.2`) -**Context:** Precision issues in IEEE 754 arithmetic. -#### ❌ Bad Practice -```javascript -if (0.1 + 0.2 === 0.3) { /* False! */ } -``` -#### ⚠️ Problem -$\text{0.1} + \text{0.2} = \text{0.30000000000000004}$ due to binary representation limits. This leads to critical bugs in financial or scientific applications. -#### ✅ Best Practice -```javascript -const EPSILON = Number.EPSILON; -const areEqual = (a, b) => Math.abs(a - b) < EPSILON; - -// Or for money: -const totalCents = (10 + 20); // 30 cents -``` -#### 🚀 Solution -Use `Number.EPSILON` for comparisons or represent decimals as integers (e.g., cents instead of dollars) to avoid floating point drift. - -### 🚨 26. Multiple Boolean flags vs State Machine -**Context:** Managing complex component logic. -#### ❌ Bad Practice -```javascript -const [isLoading, setIsLoading] = useState(false); -const [isError, setIsError] = useState(false); -const [isSuccess, setIsSuccess] = useState(false); -``` -#### ⚠️ Problem -Multiple flags allow for "impossible states" (e.g., `isLoading` and `isError` both being `true`). This makes logic branches exponentially complex. -#### ✅ Best Practice -```javascript -const [status, setStatus] = useState('IDLE'); // IDLE, LOADING, ERROR, SUCCESS -``` -#### 🚀 Solution -Use a single state variable or a state machine. This ensures only one state is active at a time and simplifies transitions. - -### 🚨 27. Sync logic in Event Loop -**Context:** Keeping the UI responsive. -#### ❌ Bad Practice -```javascript -function processLargeArray(arr) { - // Blocks the main thread for 2 seconds - arr.sort().forEach(item => complexCalc(item)); -} -``` -#### ⚠️ Problem -JavaScript is single-threaded. Heavy synchronous computation blocks the Event Loop, causing the UI to freeze and preventing user interaction. -#### ✅ Best Practice -```javascript -// Use Web Workers or break into chunks -function processInChunks(arr) { - if (arr.length === 0) return; - const chunk = arr.splice(0, 100); - process(chunk); - setTimeout(() => processInChunks(arr), 0); -} -``` -#### 🚀 Solution -Offload heavy tasks to Web Workers or use `requestIdleCallback`/`setTimeout` to break long tasks into smaller chunks, allowing the browser to render between frames. - -### 🚨 28. Overusing `classes` where functions suffice -**Context:** Paradigm choice (OOP vs FP). -#### ❌ Bad Practice -```javascript -class Calculator { - add(a, b) { return a + b; } -} -const calc = new Calculator(); -``` -#### ⚠️ Problem -Classes introduce unnecessary overhead (prototype chain, `this` binding issues) and make tree-shaking harder for bundlers. -#### ✅ Best Practice -```javascript -export const add = (a, b) => a + b; -``` -#### 🚀 Solution -Use simple functions and modules for logic. Use classes only when you need to manage complex stateful instances with shared behavior. - -### 🚨 29. Hard-coded Error messages vs Error Classes -**Context:** Robust error handling and debugging. -#### ❌ Bad Practice -```javascript -throw new Error('User not found'); -``` -#### ⚠️ Problem -Parsing error messages in `catch` blocks is brittle. If the string changes, the error handling logic breaks. -#### ✅ Best Practice -```javascript -class UserNotFoundError extends Error { - constructor(userId) { - super(`User ${userId} not found`); - this.name = 'UserNotFoundError'; - this.code = 404; - } -} -``` -#### 🚀 Solution -Extend the `Error` class to create custom error types. Use `instanceof` check in catch blocks to handle specific errors differently. - -### 🚨 30. Unhandled Rejections -**Context:** Reliability of asynchronous flows. -#### ❌ Bad Practice -```javascript -// No .catch() or try/catch -fetch('/api/data'); -``` -#### ⚠️ Problem -Unhandled rejections create silent failures. In production environments, this can lead to memory leaks as the promise state stays pending or rejected without being cleared. -#### ✅ Best Practice -```javascript -window.addEventListener('unhandledrejection', event => { - reportToSentry(event.reason); -}); -``` -#### 🚀 Solution -Always handle promise rejections. Implement a global unhandled rejection listener as a safety net for monitoring. - ---- - ---- -[⬆️ Back to Top](#) - -## IV. Professional & Niche (Senior Level) - -### 🚨 31. Memory Leaks: Unremoved Event Listeners -**Context:** Long-lived applications (SPAs). -#### ❌ Bad Practice -```javascript -window.addEventListener('resize', () => this.handleResize()); -// Component unmounts, but listener remains -``` -#### ⚠️ Problem -The event listener keeps a reference to the component/context, preventing garbage collection even after the component is destroyed. -#### ✅ Best Practice -```javascript -const handler = () => this.handleResize(); -window.addEventListener('resize', handler); -// Cleanup: -window.removeEventListener('resize', handler); -``` -#### 🚀 Solution -Always remove event listeners in cleanup phases (e.g., `componentWillUnmount` or `useEffect` return). Use `AbortController` for an even more modern approach to listener cleanup. - -### 🚨 32. Memory Leaks: Forgotten Intervals/Timeouts -**Context:** Managing temporal background tasks. -#### ❌ Bad Practice -```javascript -setInterval(() => { - fetchStatus(); -}, 1000); -``` -#### ⚠️ Problem -Intervals continue to run indefinitely until the page is closed, even if the data they process is no longer needed, consuming CPU and memory. -#### ✅ Best Practice -```javascript -const intervalId = setInterval(fetchStatus, 1000); -// Later: -clearInterval(intervalId); -``` -#### 🚀 Solution -Store the ID returned by `setTimeout` or `setInterval` and clear it when the task is no longer relevant. - -### 🚨 33. Closures inside loops (Memory/Scope issues) -**Context:** Understanding the Event Loop and closure capture. -#### ❌ Bad Practice -```javascript -for (var i = 0; i < 5; i++) { - setTimeout(() => console.log(i), 100); // Prints '5' five times -} -``` -#### ⚠️ Problem -`var` is function-scoped. By the time the `setTimeout` executes, the loop has finished and `i` is 5. Each closure shares the same reference to `i`. -#### ✅ Best Practice -```javascript -for (let i = 0; i < 5; i++) { - setTimeout(() => console.log(i), 100); // Prints 0, 1, 2, 3, 4 -} -``` -#### 🚀 Solution -Use `let` in loop headers. It creates a new binding for each iteration, ensuring the closure captures the value of `i` at that specific moment. - -### 🚨 34. Throwing Strings instead of `new Error()` -**Context:** Ensuring useful stack traces. -#### ❌ Bad Practice -```javascript -throw 'Something went wrong'; -``` -#### ⚠️ Problem -Throwing a string provides no stack trace. It makes it nearly impossible to determine where the error originated in a complex call stack. -#### ✅ Best Practice -```javascript -throw new Error('Something went wrong'); -``` -#### 🚀 Solution -Always throw an instance of `Error` (or a subclass). This captures the `stack` property, which is vital for debugging. - -### 🚨 35. Modifying Built-in Prototypes -**Context:** Ecosystem compatibility and stability. -#### ❌ Bad Practice -```javascript -Array.prototype.last = function() { - return this[this.length - 1]; -}; -``` -#### ⚠️ Problem -"Monkey patching" built-ins can lead to collisions if a future ECMAScript version implements a method with the same name but different behavior. It also breaks for-in loops if not handled carefully. -#### ✅ Best Practice -```javascript -const last = (arr) => arr[arr.length - 1]; -``` -#### 🚀 Solution -Use utility functions or wrapper classes instead of modifying global prototypes. - -### 🚨 36. Premature Optimization (e.g., bitwise for rounding) -**Context:** Readability vs Micro-benchmarks. -#### ❌ Bad Practice -```javascript -const floor = ~~x; // Double bitwise NOT to floor -``` -#### ⚠️ Problem -While `~~` is slightly faster in some engines, it makes the code cryptic. It also only works for numbers within the 32-bit integer range. -#### ✅ Best Practice -```javascript -const floor = Math.floor(x); -``` -#### 🚀 Solution -Prioritize readability. Modern JIT compilers are smart enough to optimize `Math.floor`. Only use bitwise tricks if profiling proves it's a critical bottleneck in a hot path. - -### 🚨 37. V8 Hidden Classes: Changing object shape after initialization -**Context:** V8 JIT optimization. -#### ❌ Bad Practice -```javascript -function User(name) { - this.name = name; -} -const u1 = new User('Alice'); -u1.age = 25; // Dynamically adding property -``` -#### ⚠️ Problem -V8 creates "Hidden Classes" to optimize object property access. Adding properties after initialization changes the "shape" of the object, causing V8 to drop to a slower "Dictionary Mode" for that object. -#### ✅ Best Practice -```javascript -function User(name, age) { - this.name = name; - this.age = age; -} -const u1 = new User('Alice', 25); -``` -#### 🚀 Solution -Initialize all object properties in the constructor or a factory function. Maintain a consistent object "shape" to keep V8 in the optimized path. - -### 🚨 38. Array Hole (Sparse Arrays) performance -**Context:** Memory allocation and JIT optimization. -#### ❌ Bad Practice -```javascript -const arr = new Array(100); -arr[50] = 'val'; -``` -#### ⚠️ Problem -Creating "holes" in arrays makes them "sparse". Sparse arrays are stored differently (as hash maps) which is much slower for iteration and access than "packed" arrays. -#### ✅ Best Practice -```javascript -const arr = Array.from({ length: 100 }, () => null); -``` -#### 🚀 Solution -Initialize arrays with default values (like `null` or `0`) instead of leaving empty slots. This keeps the array in "packed" mode. - -### 🚨 39. Using `eval()` or `new Function()` -**Context:** Security and performance. -#### ❌ Bad Practice -```javascript -const result = eval('2 + 2'); -``` -#### ⚠️ Problem -`eval()` executes strings as code, opening a massive XSS security vulnerability if the string contains user input. It also prevents the JIT compiler from optimizing the surrounding scope. -#### ✅ Best Practice -```javascript -const result = new Function('a', 'b', 'return a + b')(2, 2); // Slightly better, but still risky -// Better: -const operations = { '+': (a, b) => a + b }; -``` -#### 🚀 Solution -Avoid `eval()`. Use lookup tables, JSON parsing, or safe math libraries to handle dynamic logic. - -### 🚨 40. Micro-optimizations that hurt readability -**Context:** Maintaining a healthy codebase. -#### ❌ Bad Practice -```javascript -for (let i = 0, len = arr.length; i < len; i++) { /* ... */ } -``` -#### ⚠️ Problem -Caching `arr.length` was necessary 15 years ago. Today, modern engines optimize this automatically. Adding extra variables for micro-gains makes the code harder to read. -#### ✅ Best Practice -```javascript -for (const item of arr) { /* ... */ } -``` -#### 🚀 Solution -Focus on "Big O" complexity and clean code. Only micro-optimize after profiling identifies a specific performance hotspot. -======= - ## 📚 Specialized Topics For further reading, please refer to the following specialized guides: @@ -821,4 +233,3 @@ For further reading, please refer to the following specialized guides: - [✨ Modern Syntax & Functional Programming](./modern-syntax.md) - [⏳ Asynchronous & Logic](./async-logic.md) - [🧠 Professional & Niche Topics](./professional-niche.md) ->>>>>>> main