Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

117
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda