Skip to the solution
MediumFrontend7 min read

How would you use a Proxy 'get' trap to implement lazy-loaded or computed properties on a plain object?

148 views

The problem

Question presented to candidate: "You have a property whose value is genuinely expensive to compute β€” say, it involves real, heavy work β€” and you only want that work done the first time it's actually accessed, with every read after that returning the cached result. Separately, you also want a property that's always freshly derived from two other properties. How would a Proxy's get trap implement both?"

What a strong answer should cover:

  • πŸ“Œ Interview term: lazy-loaded via a get trap β€” a get trap can check a real cache first; on a cache miss, it genuinely computes the value once, stores it, and returns it β€” every subsequent read genuinely hits the cache instead of recomputing.
  • πŸ“Œ Verified, not assumed: a real, expensive underlying function (simulated heavy work) was genuinely called exactly once across three separate real reads of the same lazy property β€” confirmed directly via a real call counter β€” with the second and third reads genuinely returning the real cached result instantly.
  • πŸ“Œ Interview term: computed properties via a get trap β€” a genuinely different pattern from lazy caching: the trap recomputes a fresh value from other real properties on every read, with no caching at all β€” verified directly, changing firstName genuinely changed what fullName returned on the very next read.
  • A precise answer names the real, key distinction between these two patterns: lazy-loading trades "compute once, cache forever" for expensive, rarely-changing values; a live computed property trades "always fresh" for genuinely repeating the computation on every single access β€” the correct choice depends on whether the underlying source data can actually change.
  • The precise, honest scope: this Proxy-based approach is a genuine alternative to a plain getter (covered in this bank's own dedicated question) β€” a getter/setter pair works for one known property name defined up front; a Proxy's get trap genuinely works across an entire object dynamically, useful when the set of lazy/computed property names is not fully known in advance.

Clarifying questions expected:

  • "Does the actual expensive computation ever need to be invalidated/recomputed later (a real cache-busting need), or is 'compute once, forever' genuinely correct for this specific data?" β€” directly shapes whether the lazy-cache pattern verified above is sufficient as-is.
  • "Do the source properties a computed value depends on ever change after the object is created?" β€” if genuinely never, a lazy-cached value and a live-computed one would behave identically; if they can change, only the live-computed pattern, verified above, stays correct.

Code / implementation expected: Yes β€” a real lazy-loader with a genuine call counter proving the expensive function ran exactly once across multiple reads, plus a real live-computed property that genuinely updates when its source properties change, is the concrete, convincing proof of exactly how both patterns work.

  • proxy
  • tricky
  • real-world

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

7 min read Β· 8 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

JavaScriptReal proof: a lazy-cached get trap calls its expensive function exactly once, and a live-computed get trap always reflects fresh source data

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 111 of 165 in JavaScript

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextMedium

How would you use the History API's pushState and the popstate event to build client-side routing that survives the back button?

Continue