Did you know you can attach a key to a JavaScript object that is actually a callable?

For example:


const data = await response.json()

Object.defineProperty(data, 'magic', {
  get: () => {
    return Math.random()
  },
})

console.log({magic: data.magic})

will print:

{ magic: 0.6778944803790492 }

And suppose you want it memoized, you can use this:


const data = await response.json()

let magic
Object.defineProperty(data, 'magic', {
  get: () => {
    return magic ??= Math.random()
  },
})

console.log({magic: data.magic})
console.log({magic: data.magic})
console.log({magic: data.magic})

will print:

{ magic: 0.21367035961590308 }
{ magic: 0.21367035961590308 }
{ magic: 0.21367035961590308 }

Note that it doesn't allow setting. If you do this:


Object.defineProperty(data, 'magic', {
  get: () => {
    return Math.random())
  },
  set: () => {
    throw new Error('Nope!')
  },
})

data.magic = 42

it will print:

Error: Nope!

One thing that bit me today, and much the reason why I'm writing this, is that I had this:


async function getData() {
  const response = await get()
  const data = await response.json()

  Object.defineProperty(data, 'magic', {
    get: () => {
      return Math.random()
    },
  })

  return {...data}
}


// Example use:

const {userName, magic} = await getData()
console.log({userName, magic})

// Will print
// { userName: 'peter', magic: undefined }

This does not work because the magic property is not enumerable. To fix that, make this edit:


  Object.defineProperty(data, 'magic', {
    get: () => {
      return Math.random()
    },
+   enumerable: true,
  })

Now, the same code as above, when you run console.log({userName, magic}) it will print:

{ userName: 'peter', magic: 0.23560450431932733 }

Comments

Your email will never ever be published.

Previous:
Wouter + Vite is the new create-react-app, and I love it August 16, 2024 Node, React, Bun
Next:
swr compared to @tanstack/react-query August 30, 2024 JavaScript
Related by category:
You don't need a context or state manager for TanStack Query in scattered React components January 2, 2026 JavaScript
Always run biome migrate after upgrading biome August 16, 2025 JavaScript
Video to Screenshots app June 21, 2025 JavaScript
Starting a side project: PissueTracker March 16, 2025 JavaScript
Related by keyword:
How to simulate slow lazy chunk-loading in React March 25, 2021 React, JavaScript
React 16.6 with Suspense and lazy loading components with react-router-dom October 26, 2018 Web development, React, JavaScript
Using lazy loading images on Air Mozilla April 23, 2015 Mozilla, JavaScript