How to define conditional properties for a literal object in the leanest way possible with Javascript?

Asked

Viewed 192 times

2

I would like to know how to add conditional properties to a literal object in the leanest way possible.

I currently declare the object and then add the conditional properties as in the following example:

function getFamilia(avos) {
  const familia = {
    filhos: ['Pedro', 'Claudia'],
    pais: ['Marcio', 'Fernanda']
  }

  if (avos) {
     familia.avos = avos
  }

  return familia
}

I have tried to make a ternary in the definition of the object but the key remains there even if it returns Undefined. Example:

const getFamilia = avos => ({
  filhos: ['Pedro', 'Claudia'],
  pais: ['Marcio', 'Fernanda'],
  avos: avos || undefined
})

Is there any way to make conditional directly in the object declaration without leaving the key there in the false case?

You can use any feature of any javascript version.

  • I can’t understand at all, um... what you want is that property 'avos' does not exist?

  • 1

    Exact @Matheus. If she has a value she wanted the object to have the property filled. If not, she wanted it not to exist in the object.

2 answers

1


Your object creation is with a wrong definition. What you are doing is a function that returns an object and not a class in javascript. With a class you can guarantee that the attribute will exist because it is defined in it.

/*
 *  JS Class
 *
  function Familia(filhos, pais, avos) {
    if(filhos) this.filhos = filhos;
    if(pais) this.pais = pais;
    if(avos) this.avos = avos;
  }
/*
 */
 
/*
 *  ES6 Class
 */
class Familia {
  constructor(filhos, pais, avos) {
    if(filhos) this.filhos = filhos;
    if(pais) this.pais = pais;
    if(avos) this.avos = avos;
  }
}
/*
 */
 

let familiaCompleta = new Familia(['Pedro', 'Claudia'], ['Marcio', 'Fernanda'], ['Frank']);
console.log(familiaCompleta);

let semFilhos = new Familia(null, ['Marcio', 'Fernanda'], ['Frank']);
console.log(semFilhos);

let semPais = new Familia(['Pedro', 'Claudia'], null, ['Frank']);
console.log(semPais);

let semAvos = new Familia(['Pedro', 'Claudia'], ['Marcio', 'Fernanda'], null);
console.log(semAvos);

  • did not solve the problem. Created the object with the avos property equal to null besides being extremely verbose than the other solutions.

  • And just for the record, you don’t need a class to create objects in javascript. The two functions in the example return an object. The difference is that they are not the instance of a class, but remain objects.

  • You can put the default values as shown in the comment: this.filhos = filhos || []; Although it is more "verbose" it returns a true class allowing Voce to have better use of POO.

  • But if Voce goes to see the class in ES6 required more lines to type, even so Voce can opt for the class vanilla, which is commented, which is smaller than your example presented in the question.

  • has escaped the scope of the question. I want the object to only have the avos property if the avos parameter exists. Otherwise I would like the object not to have the property.

  • I had understood that Voce wanted a way to treat the value of a class property in a few lines, not that Voce was going to remove the property.

  • Not to remove. It is to add conditionally. If you have add, if you do not have add. I would not like to have the avos property equal to null or undefined. I wish it didn’t even exist in the definition of the object if it doesn’t exist.

  • In that case I’m making the change

  • Okay, that’s the cleanest way possible. Although if you think about object orientation, conceptually this is not the right thing to do (only weighing on the integrity of objects)

  • It’s still very verbose, but apparently it’s the leanest form.

Show 5 more comments

0

It is possible to resolve the action of defining that property (recognized as [[PUT]] by the Ecmascript specifications, or "set"), or reading ([[GET]], or "get") on the object. This is only directly available on Ecmascript 5 and above (mainly on Ecmascript 6).

Creating a Proxy you can control all actions of [[PUT]] at once (looks a lot like the meta(Moon’s Tables)) on the same object.

const meta = {
    set: (f, prop, value) => {
        // Toda propriedade deve conter um objeto.
        if (value instanceof Object) {
            f[prop] = value
            return true
        }
        // Não redefine a propriedade nesse caso.
        return false
    }
}

const getFamilia = avos => {
    var init = {
        filhos: ['Pedro', 'Claudia'],
        pais: ['Marcio', 'Fernanda']
    }
    var f = new Proxy(init, meta)
    f.avos = avos
    return f
}

The Proxy comes from ES6.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.