Kazi Rahamatullah
Kazi Rahamatullah
AboutProjectsBlogContact
UsesBooks
ResumeView CV
Kazi Rahamatullah

© Copyright 2026 Kazi Rahamatullah

AboutProjectsBlogBooksUses
Twitter/XGitHubProduct HuntCodeSandbox
Back to Blog
JavaScriptCode SnippetsUtilitiesInterview PreparationFrontend Development

JavaScript Important Code Snippets

Production-ready JavaScript utilities — debounce, throttle, deep clone, shuffle, groupBy, flatten, dedupe, date formatting, and safe nested access with interview-ready callouts.

Jul 3, 202611 min read

Introduction

A curated set of production-ready JavaScript snippets — each with runnable code, practical notes, performance guidance, and interview-ready answers. Use the quick index to jump to any utility.

Snippet Reference

Quick index

#SnippetDescription
1DebounceWait until the user stops triggering an event before running the handler
2ThrottleEnsure a function runs at most once per time window
3Deep CloneCreate a fully independent copy of nested objects and arrays without mutating the original.
4Shuffle Array ElementsRandomly reorder array elements using the Fisher–Yates algorithm for an unbiased shuffle.
5Generate Unique KeyCreate short unique identifiers for React list keys, temp IDs, and client-side tracking.
6Group Array Elements by KeyPartition an array of objects into buckets keyed by a property value.
7Flatten Nested ArrayConvert a deeply nested array into a single flat array of values.
8Remove DuplicatesDeduplicate primitive arrays with Set or object arrays by a specific key.
9Format DateFormat dates for display using Intl.DateTimeFormat with locale-aware output.
10Safe Access HelperRead deeply nested properties from an object using a dot-path string without throwing on missing keys.

1. Debounce

Wait until the user stops triggering an event before running the handler — ideal for search inputs and resize listeners.

javascript
// Debounce: wait until user stops typing for `delay` ms
function debounce(func, delay) {
  console.log('In debounce...')
  let timer // holds timeout id
  return function (...args) {
    clearTimeout(timer) // cancel previous pending call
    timer = setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}
 
const search = debounce((q) => console.log('Search for:', q), 500)
 
search('J')
search('Ja')
search('Jav')
search('Java')
// Only one console log: "Search for: Java" after 300ms

Note

Each new call clears the previous setTimeout timer. Only the last invocation within the delay window executes.

Tip

Use debounce for search boxes, auto-save drafts, and form validation on input — anywhere you want to react after the user pauses.

Performance

Debouncing a search input from firing on every keystroke can reduce API calls from hundreds to one per query.

Interview Answer

Debounce delays execution until activity stops. Throttle limits execution to once per interval. Search → debounce; scroll position tracker → throttle.

Back to index


2. Throttle

Ensure a function runs at most once per time window — ideal for scroll, resize, and mousemove handlers.

javascript
// Throttle: ensure func runs at most once per `limit` ms
function throttle(func, limit) {
  let lastCall = 0
  return function (...args) {
    const now = Date.now()
    if (now - lastCall >= limit) {
      lastCall = now
      func.apply(this, args)
    }
  }
}
 
// Usage
 
window.addEventListener(
  'scroll',
  throttle(() => {
    console.log('throttled scroll event')
  }, 200),
)

Note

lastCall tracks the timestamp of the previous execution. Calls inside the limit window are ignored.

Tip

Use throttle for scroll, resize, and infinite-scroll loaders where you need periodic updates, not a final settled value.

Performance

Throttling scroll handlers to 100–200ms keeps the main thread responsive while still updating UI often enough to feel live.

Interview Answer

Throttle guarantees a maximum call rate. Debounce waits for silence. A scroll spy that updates a nav highlight should use throttle, not debounce.

Back to index


3. Deep Clone

Create a fully independent copy of nested objects and arrays without mutating the original.

javascript
// Deep clone using structuredClone (modern browsers / Node 17+)
// structuredClone preserves Dates, RegExp, Maps, Sets, and doesn't run code.
function deepClone(obj) {
  return structuredClone(obj)
}
 
// Simple fallback: JSON deep copy — works for plain objects (no Date/Map/Set/functions)
function deepCloneFallback(obj) {
  return JSON.parse(JSON.stringify(obj))
}
 
// Usage
 
const original = { name: 'A', meta: { joined: new Date(), tags: ['js'] } }
const copy = typeof structuredClone === 'function' ? deepClone(original) : deepCloneFallback(original)
 
copy.meta.tags.push('node')
console.log(original.meta.tags) // original unaffected: ["js"]

Note

structuredClone handles Date, RegExp, Map, Set, and ArrayBuffer. The JSON fallback only works for plain JSON-serializable data.

Tip

Prefer structuredClone in modern browsers and Node 17+. Fall back to JSON only for simple config objects.

Warning

JSON.parse(JSON.stringify(obj)) strips functions, converts Dates to strings, and drops undefined values. Never use it for complex state clones.

Interview Answer

Shallow copy ({...obj}, Object.assign) copies top-level references only. Deep clone duplicates nested structures — required before mutating nested state immutably.

Back to index


4. Shuffle Array Elements

Randomly reorder array elements using the Fisher–Yates algorithm for an unbiased shuffle.

javascript
// Fisher–Yates shuffle — unbiased random shuffle
function shuffle(array) {
  const arr = [...array] // copy to avoid mutating original
  for (let i = arr.length - 1; i > 0; i--) {
    // pick random index from 0..i
    const j = Math.floor(Math.random() * (i + 1))
    // swap arr[i] and arr[j]
    ;[arr[i], arr[j]] = [arr[j], arr[i]]
  }
  return arr
}
 
// Usage
 
const deck = [1, 2, 3, 4, 5, 6]
console.log(shuffle(deck)) // shuffled array

Note

Copy the array with spread ([...array]) before shuffling so the original order is preserved.

Tip

Fisher–Yates runs in O(n) and produces uniformly random permutations — unlike sort(() => Math.random() - 0.5) which is biased.

Performance

In-place Fisher–Yates avoids extra allocations. Use a copy when immutability matters (React state, Redux).

Interview Answer

Sorting with a random comparator does not produce a fair shuffle. Fisher–Yates iterates backward, swapping each index with a random earlier index.

Back to index


5. Generate Unique Key

Create short unique identifiers for React list keys, temp IDs, and client-side tracking.

javascript
// Simple short id — not cryptographically secure, but okay for UI keys
function uniqueId() {
  // toString(36) makes it shorter (0-9a-z)
  return Math.random().toString(36).substring(2, 10)
}
 
// Use timestamp + random to reduce collision probability
function uniqueIdSafe() {
  return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 8)}`
}
 
// Node/browser crypto (secure)
function uniqueIdCrypto() {
  // browser: crypto.getRandomValues; Node: require('crypto').randomBytes
  return crypto.randomUUID() // modern API (UUID v4), if available
}
 
// Usage:
 
console.log(uniqueId()) // ex: "k9x3f8q0"
console.log(uniqueIdSafe()) // ex: "l8k3x-9f2t3p"
console.log(uniqueIdCrypto())

Note

Math.random().toString(36) is fine for UI keys but is not cryptographically secure.

Tip

Combine Date.now() with random bytes to reduce collision risk in fast loops. For React keys, stable IDs from the server are always better.

Warning

Never use Math.random() for session tokens, payment IDs, or anything security-sensitive. Use crypto.randomUUID() instead.

Interview Answer

React keys must be stable and unique among siblings. Index keys break on reorder/filter. Use server IDs when available; generate client IDs only as a fallback.

Back to index


6. Group Array Elements by Key

Partition an array of objects into buckets keyed by a property value.

javascript
// Group by key using reduce
function groupBy(arr, key) {
  return arr.reduce((acc, item) => {
    const groupKey = item[key]
    // if group doesn't exist, init as array
    if (!acc[groupKey]) acc[groupKey] = []
    acc[groupKey].push(item)
    return acc
  }, {})
}
 
// Usage
 
const users = [
  { name: 'A', role: 'dev' },
  { name: 'B', role: 'pm' },
  { name: 'C', role: 'dev' },
]
console.log(groupBy(users, 'role'))
 
// For modern browsers and Node environment
const grouped = Object.groupBy(users, (user) => user.role)
console.log(grouped)

Note

The reduce pattern works in all environments. Object.groupBy (ES2024) is the native shorthand when available.

Tip

Initialize missing groups as empty arrays inside the reducer. For Map-based grouping, use Map when keys are not strings.

Performance

Single-pass reduce is O(n). Multiple .filter calls per group would be O(n × groups).

Interview Answer

Group-by is a classic reduce interview problem. Know both the manual reduce version and Object.groupBy for modern runtimes.

Back to index


7. Flatten Nested Array

Convert a deeply nested array into a single flat array of values.

javascript
// Recursive flatten — handles arbitrary nesting
function flatten(arr) {
  return arr.reduce((flat, item) => {
    if (Array.isArray(item)) {
      return flat.concat(flatten(item))
    }
    return flat.concat(item)
  }, [])
}
 
// Usage:
console.log(flatten([1, [2, [3, 4]], 5])) // [1,2,3,4,5]
 
console.log([1, [2, [3, 4]], 5].flat(Infinity))

Note

Recursive reduce handles arbitrary nesting depth. Array.prototype.flat(Infinity) is the built-in equivalent.

Tip

Use flat(1) when you only need one level. Use flat(Infinity) or recursion when depth is unknown.

Performance

Native flat is implemented in C++ inside the engine and is faster than hand-rolled recursion for large arrays.

Interview Answer

Recursive flatten walks each element — if array, recurse; else push. Know the iterative stack-based version for follow-up depth questions.

Back to index


8. Remove Duplicates

Deduplicate primitive arrays with Set or object arrays by a specific key.

javascript
// Simple and fast using Set (preserves insertion order)
const removeDuplicates = (arr) => [...new Set(arr)]
 
// Usage
 
console.log(removeDuplicates([1, 2, 2, 3, 4, 4])) // [1,2,3,4]
 
// For arrays of objects (by key)
 
function uniqueBy(arr, key) {
  const seen = new Set()
  return arr.filter((item) => {
    const k = item[key]
    if (seen.has(k)) return false
    seen.add(k)
    return true
  })
}

Note

Set preserves insertion order in modern JavaScript. Spread [...new Set(arr)] returns a new array without mutating the original.

Tip

For objects, track seen keys in a Set inside .filter. Map keyed by the property also works and keeps the last occurrence.

Performance

Set lookup is O(1) average. Filtering with .indexOf per element is O(n²) — avoid on large arrays.

Interview Answer

Two-pointer sort-then-dedupe works on sorted arrays in O(n). For unsorted primitives, Set spread is the cleanest one-liner.

Back to index


9. Format Date

Format dates for display using Intl.DateTimeFormat with locale-aware output.

javascript
// Format date using Intl.DateTimeFormat (reliable & localizable)
function formatDate(dateInput, locale = 'en-US', options = { year: 'numeric', month: 'short', day: 'numeric' }) {
  const date = new Date(dateInput)
  if (Number.isNaN(date.getTime())) return 'Invalid Date'
  return new Intl.DateTimeFormat(locale, options).format(date)
}
 
// Usage
 
console.log(formatDate('2025-01-15')) // "Jan 15, 2025" (en-US)
console.log(formatDate('2025-01-15', 'en-GB')) // "15 Jan 2025"

Note

Always validate with Number.isNaN(date.getTime()) before formatting — invalid strings return "Invalid Date".

Tip

Pass locale and options for i18n. timeZone in options ensures consistent display across user regions.

Warning

Parsing date strings is timezone-sensitive. "2025-01-15" is UTC midnight; "01/15/2025" may parse as local. Prefer ISO 8601 from APIs.

Interview Answer

Avoid manual string concatenation for dates. Intl.DateTimeFormat handles locale rules. For relative time ("2 hours ago"), use Intl.RelativeTimeFormat.

Back to index


10. Safe Access Helper

Read deeply nested properties from an object using a dot-path string without throwing on missing keys.

javascript
// safeGet: read nested path safely, return fallback if path not present
function safeGet(obj, path, fallback = null) {
  return (
    path.split('.').reduce((acc, key) => {
      return acc?.[key]
    }, obj) ?? fallback
  )
}
 
// Usage:
 
const user1 = {
  id: 101,
  name: 'Garima',
  address: { city: 'Kolkata', pin: 700001 },
}
 
const user2 = {
  id: 102,
  name: 'Geeta',
  // address missing (maybe from incomplete API)
}
 
console.log(safeGet(user1, 'address.city', 'Unknown City')) // "Kolkata"
console.log(safeGet(user2, 'address.city', 'Unknown City')) // "Unknown City"
console.log(safeGet(user2, 'preferences.theme', 'light')) // "light"
 
// Alternative short using optional chaining directly. But safeGet is handy when path is dynamic (string).
const city = user2?.address?.city ?? 'Unknown City'

Note

Optional chaining (obj?.a?.b) works for static paths. safeGet shines when the path is dynamic — built from user input or config.

Tip

Use the nullish coalescing operator (??) for fallbacks. || treats 0 and "" as falsy; ?? only falls back on null/undefined.

Performance

Splitting the path string each call has minor cost. For hot loops, cache the key array or use a compiled accessor.

Interview Answer

Implement safeGet with reduce and optional chaining per step. Compare to Lodash _.get — same idea, know how to write it without a library.

Back to index


Share this article

XLinkedInFacebook
Kazi Rahamatullah

Written by

Kazi Rahamatullah

FullStack Developer

X / TwitterGitHubLinkedIn

Subscribe to my newsletter

Stay up to date and get notified when I share new contents.

No spam ever, unsubscribe anytime