Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

114
Views
JavaScript Proxy which returns an empty array by default

I want to define some object so that every property provides an empty array if it's not defined.

Example: consider the list of users, every user is {id: number, age: string, ...}. We want to group users by age:

const users = [{id: 1, age: 42}, {id: 2, age: 42}, {id: 3, age: 43}]

const usersByAge = users.reduce((out, user) => {
  if (!out.hasOwnProperty(user.age)) {
    out[user.age] = []
  }
  out[user.age].push(user)
  return out
}, {})

console.log(usersByAge[42]) -> [{id: 1, age: 42}, {id: 2, age: 42}]
console.log(usersByAge[43]) -> [{id: 3, age: 43}]
console.log(usersByAge[18]) -> undefined
console.log(Object.keys(usersByAge)) -> ['42', '43']

This code works, but I want to shorten it by using special JavaScript Proxy. It should return an empty array if the property is not defined. It should be possible to push items into the property even if it's not defined. It should provide the same array for different undefined properties:

const getMapFromIdToArray = () => {
  return new Proxy({}, {
    get: (target, name) => {
      if (!target.hasOwnProperty(name)) {
        target[name] = []
      }
      return target[name]
    }
  })
}

const usersByAge = users.reduce((out, user) => {
  out[user.age].push(user) // <- this should work, array initialization should not be required
  return out
}, getMapFromIdToArray())

console.log(usersByAge[42]) -> [{id: 1, age: 42}, {id: 2, age: 42}] - OK
console.log(usersByAge[18]) -> [] - OK
console.log(usersByAge[18] === usersByAge[19]) -> true - FAIL
console.log(Object.keys(usersByAge)) -> ['42', '43'] - FAIL

This code works partly. If the property is not defined, it's initialized as []. So the getter actually mutates the target. I would like to avoid this. But the same time I want to be able to call .push on an undefined property without initialization. Is it possible to achieve?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

It should provide the same array for different undefined properties

I'm not sure what you meant in this sentence, but you definitely don't want two different properties to return reference to the same array and then items belonging to different properties being pushed to that array.

If the property is not defined, it's initialized as []. So the getter actually mutates the target. I would like to avoid this. But the same time I want to be able to call .push on an undefined property without initialization. Is it possible to achieve?

I would say yes and no. The push method has to work on an actual array, and the object must hold a reference to that array in order to retrive the pushed items later. But if you don't want the empty array to create an actual property in the target object right away, then you can store it separately in the proxy until it requested after being mutated:

new Proxy({}, {
  tempProps: {},
  get: (target, name, reciever) => {
    if (target.hasOwnProperty(name)) {
      return target[name];
    }

    if (tempProps.hasOwnProperty(name)) {
      if tempProps[name].length {
        // array is not empty - bring into target
        target[name] = tempProps[name];
        delete tempProps[name];
        return target[name];
      } else {
        return tempProps[name];
      }
    }

    tempProps[name] = [];
    return tempProps[name];
  }
})

It may also be possible to hold the reference to the returned empty array in a WeakRef object, so that if the caller drops all references to the array it will finally be garbage collected. But that seems unnecessarily complicated unless in very specific circumstances.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!