Apply equal properties to different JS objects

Asked

Viewed 59 times

-2

I would like to know how do I encapsulate identical properties that are being assigned to different objects. For example:

In my code, there is a 'first' object, which is located inside a class, and has a property called 'redirection', which is also in other objects, like 'Second' and 'third'. I’d like to know how I do, all at once, to apply this same property to all these objects at once, as is common in CSS, for example.

2 answers

1


Yes it is natively possible to cause different instances in javascript may have one or more linked properties in such a way that the change of one of these linked properties in any of the coordinated instances is reflected by all other.

It’s a design pattern called Binding Properties Pattern. This pattern is usually used in concurrent code but can be used in single thread code. This pattern derives from the paradigm of Programming Oriented to Aspects.

The original pattern consists of combining several Observers, pattern that defines a one-to-many dependency between objects so that when an object changes the state its dependents are notified, in order to force properties on different objects to coordinate themselves.

In case the language is prototyping and being single thread allows me to make a simplification in the pattern Binding Properties where instead of implementing it based on Observers I can implement it over a Proxy.

Proxy is nothing more than an object that controls access to another, here will play the role of Observer in the standard Binding Properties, but instead of notifying an event it will make a direct modification to the proxiated object.

OBS: If the code is applied to objects encapsulated in different Workers the original implementation with Observer Pattern should be resumed.

In javascript the proxy project pattern is implemented by Proxy native interface.

The algorithm is simple:

  • First three distinct classes are defined using construction functions.

  • Then the classes are instantiated and by assignment breakdown route their references are linked to their respective identifier variables.

  • A log of the properties is made redirection of each of these bodies.

  • Handler is created for the proxy:

    const BindingPatternHandler = {
      //Conjunto dos objetos dependentes.
      targets: new Set(),          
      //Disparado no proxy a qualquer alteração em suas propriedades.                  
      set: function(self, prop, value, receiver) {
              //Se a propriedade modificada for 'redirection'...
              if (prop === 'redirection'){
                  //...para cada um dos objetos proxiados..
                  for (let target of this.targets){
                      target.redirection = value       //...repassa a modificação.
                  }
              }
      }
    }
    
  • The function that applies the pattern to a given instance is created:

    //Cria o proxy para o objeto e o coloca como dependente do proxy.
    function bindingPattern(obj){
      BindingPatternHandler.targets.add(obj);
      return new Proxy(f, BindingPatternHandler);
    }
    
  • It is applied the three instances previously created.

  • And then three simple tests are done where it is demonstrated that by modifying the property redirection in any of the proxiated instances all other proxiated instances will also have the property redirection modified with the same value.

Solution:

//Define três classes distintas.  
const First = function(){
   this.redirection="First";
};

const Second = function(){
   this.redirection="Second";
};

const Third = function(){
   this.redirection="Third";
};

//Instancia três objetos das classes anteriormente declaradas.
let [f, s, t] =[new First(), new Second(), new Third()];

//Loga as propriedades ainda não sincronizadas.
console.log('Valores de redirection antes de aplicar Binding Pattern');
console.log([f.redirection,s.redirection,t.redirection]);

const BindingPatternHandler = {        
    targets: new Set(),
    set: function(self, prop, value, receiver) {                
            if (prop === 'redirection'){                    
                for (let target of this.targets){
                    target.redirection = value;       
                }
            }
    }
}

function bindingPattern(obj){
    BindingPatternHandler.targets.add(obj);
    return new Proxy(f, BindingPatternHandler);
}

//Aplica o padrão as instancias "f", "s" e "t".
[f, s, t] = [f, s, t].map(bindingPattern);

//Realiza os testes de coordenação das propriedades.
console.log('Teste nº 1 do Binding Pattern: f.redirection = "teste1"');
f.redirection = "teste1";
console.log([f.redirection,s.redirection,t.redirection]);

console.log('Teste nº 2 do Binding Pattern: s.redirection = "teste2";');
s.redirection = "teste2";
console.log([f.redirection,s.redirection,t.redirection]);

console.log('Teste nº 3 do Binding Pattern: t.redirection = "teste3";');
t.redirection = "teste3";
console.log([f.redirection,s.redirection,t.redirection]);

-1

As far as I know these days, there is no native way to do this in JS.

What can be done is to create an auxiliary function that creates a property with a value in passed objects as argument for that function:

function inserePropriedadeComValorNoObjeto(objeto, propriedade, valor) {
 objeto[propriedade] = valor;
}

From this, you can call the function by passing what you need in a repeat loop forEach in an array, just as an example:

arrayDeObjetos.forEach(objeto => { 
  inserePropriedadeComValorNoObjeto(objeto, 'redirection', 'valor')
})

It is also possible to change forEach for map and return a new object array with the properties you want, just return the function object inserePropriedade... after inserting the property, such as return objeto at the end of it:

const novoArrayDeObjetosComPropriedadeRedirection = arrayDeObjetos.map(objeto => inserePropriedadeComValorNoObjeto(objeto, 'redirection', 'valor'))

Your function would be:

function inserePropriedadeComValorNoObjeto(objeto, propriedade, valor) {
  objeto[propriedade] = valor;
  return objeto;
}

If you prefer, you can call the function for each object manually without using the return. The function will insert a property into the object you passed as argument, changing it by reference.

I hope I’ve helped in some way.

  • Got it bro. Very well explained. Congratulations on the knowledge.

Browser other questions tagged

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