I want independent variables

1

I have a variable that is an object with 2 nodes:

var jDef = {id: 'hola', valores: [{cod: 1, desc: 'dddd'}, {cod: 2, desc: 'bbbb'}]}

In another part of the program, I do:

var jTemp.valores[1] = $.extend(jDef.valores[1], {selected: true});

This works as I hope.

If I have it this way (function that picks up the list of a BBDD):

var jDef = {id: 'hola', valores: obtenerListaBBDD()};
var jTemp = $.extend({ },  jDef);
jTemp.valores[1] = $.extend(jDef.valores[1], {selected: true});

The new node 'selected' appears in both variables (jDef and jTemp), when I want it to only be included in jTemp.

Can someone clarify the concepts or give me a solution?

I have mounted a jsFiddle link

Greetings,

SeakOink (I have edited question, since it was not accurate)

EDIT:

This is the real code. jCRUD.Datatable [n] .valors_admesos [1] has the same value as jTemp.valors_admesos [1] (with the new node "selected":

        var jTemp = $.extend({}, jCRUD.DataTable[n], {data: sValor}); //Subtitueix el node "data" amb el valor calculat
        nn = 0;
        nnTotal = _.size(jTemp.valors_admesos);
        while (nn < nnTotal) {
            // Bucle en cas de tenir una llista de valors en un <select>, el qual marcarà com a "selected" el <option> que correspon al valor
            if (jTemp.valors_admesos[nn].valor === sValor) {
                jTemp.valors_admesos[nn] = $.extend({}, jTemp.valors_admesos[nn], {selected: 'selected'}); // Marco el valor del camp com a seleccionat a dins la llista
            }
            nn++;
        }
    
asked by Seak 12.11.2016 в 12:50
source

1 answer

1
  

From the jQuery documentation:

     

$.extend( target, obj1, \[ obj2 \] )
  Add the contents of obj1, obj2, to the target , and return the latter.

That is to say, that the correct and expected behavior is what you think is wrong. The weird is the first case, which as you say, does not do the same ... Are you sure that in the first case you expose, both , jTemp and jDef , do not end with the same attributes?

  • If you want to add an attribute to an already created object, it's as easy as making a simple assignment.

  • If what you want is to obtain an object that mixes other 2, it would be:

    result = $.extend( { }, obj1, obj2 }
    


Description

$.extend( ) extends the object passed as the first argument with the attributes of the other objects, and returns that first argument. As we passed an empty object, without previous content, copy the content of the other 2 objects on that empty object ; at the end, target contains all the attributes contained in the other 2, which have not been modified.

Finally, $.extend( ) returns the object that we passed as the first argument (remember that the objects are passed by reference ), so we already have our operation union done.


Example:

function obtenerBBDD() {
    return [{cod: 1, desc: '111'}, {cod: 2, desc: '222'}];
}

var jDef = {id: 'hola', valores: obtenerBBDD()};
// jDef = {"id":"hola","valores":[{"cod":1,"desc":"111"},{"cod":2,"desc":"222"}]}

var jTemp = $.extend({ },  jDef);
// jTemp = {"id":"hola","valores":[{"cod":1,"desc":"111"},{"cod":2,"desc":"222","selected":true}]}

Here we start with the problems. jTemp["valores"] is not a separate object, it is a reference at "valores" contained in jDef .

That is, jTemp.valores is the same object as jDef.valores . Therefore, any change to one of them affects the other.

Possible solutions

  • Use $.extend( ) with an initial true argument, to make a recursive copy:

    var jTemp = $.extend( true, { }, jDef )
    

    According to the documentation, that true initial% will force the recursive copy, so that jTemp and jDef are not linked, and the problem is resolved.

  • Use another library, which does a deep copy , if jQuery does not allow it.

  • answered by 12.11.2016 / 13:19
    source