Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

113
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda