J'ai le problème suivant:

Une bibliothèque renvoie une référence sur un objet. Maintenant, je ne veux pas modifier uniquement des parties uniques de l'objet, je veux remplacer complètement l'objet.

Mon code ressemble à ceci:

var options=getOptions();
options=newOptions;
// now do something with the new options.

Mais lorsque j'exécute ce code, la référence sera supprimée et une nouvelle sera définie.

Alors, comment puis-je copier un tout nouvel objet dans la référence?

-1
Jonas Embach 11 avril 2018 à 10:50

3 réponses

Meilleure réponse

Vous remplacez l'objet auquel vous faites référence par options, mais cela n'a aucun effet sur toute référence à l'objet d'origine de la bibliothèque. Il n'y a rien que vous pouvez faire avec la valeur de retour de getOptions qui remplacera l'objet de la bibliothèque par un objet entièrement nouveau; tout ce que vous pouvez faire est de changer l'état de l'objet qu'il vous donne (ajout, modification et / ou suppression de propriétés).

À moins que la bibliothèque ne vous fournisse un moyen de modifier l'objet auquel elle fait référence en interne, vous ne pouvez pas remplacer complètement cet objet (sans modifier la bibliothèque).

Voici un exemple pour illustrer:

// Emulating the library:
var lib = (function() {
  var libOptions = {
    name: "original"
  };
  
  return {
    // The operation you said it has
    getOptions: function() {
      return libOptions;
    },
    // The operation it would need to have
    setOptions: function(newOptions) {
      libOptions = newOptions;
    }
  };
})();

var options = lib.getOptions();
options = {
  name: "replaced"
};

console.log(options.name);          // "replaced"
console.log(lib.getOptions().name); // "original"

lib.setOptions(options);

console.log(options.name);          // "replaced"
console.log(lib.getOptions().name); // "replaced"

Lorsque la bibliothèque vous donne une référence à son objet, vous avez quelque chose comme ça en mémoire:

libOptions−−+
            |
            |   +−−−−−−−−−−−−−−−−−−+
            +−−>|     (object)     |
            |   +−−−−−−−−−−−−−−−−−−+
            |   | name: "original" |
options−−−−−+   +−−−−−−−−−−−−−−−−−−+

Ensuite, lorsque vous définissez options sur autre chose:

                +−−−−−−−−−−−−−−−−−−+
libOptions−−−−−>|     (object)     |
                +−−−−−−−−−−−−−−−−−−+
                | name: "original" |
                +−−−−−−−−−−−−−−−−−−+

                +−−−−−−−−−−−−−−−−−−+
options−−−−−−−−>|     (object)     |
                +−−−−−−−−−−−−−−−−−−+
                | name: "replaced" |
                +−−−−−−−−−−−−−−−−−−+

Comme vous pouvez le voir, la définition de options n'a aucun effet sur la référence de la bibliothèque dans libOptions.

C'est pourquoi la bibliothèque devrait fournir setOptions.

Bien sûr, encore une fois, vous pouvez changer l'état de l'objet (à condition que la bibliothèque ne vous donne pas une copie défensive ou un objet gelé);

options.name = "updated";

Ce qui fait ceci:

libOptions−−+
            |
            |   +−−−−−−−−−−−−−−−−−−+
            +−−>|     (object)     |
            |   +−−−−−−−−−−−−−−−−−−+
            |   | name: "updated"  |
options−−−−−+   +−−−−−−−−−−−−−−−−−−+
0
T.J. Crowder 11 avril 2018 à 08:03

Merci pour votre aide. Je comprends le problème.

J'ai maintenant résolu le problème d'une manière vraiment sale ... Quand j'ai des options modifiées, je détruis l'objet lib et j'en crée un nouveau. Ce n'est pas la bonne solution mais une solution.

0
Jonas Embach 16 avril 2018 à 19:30

Ce que je comprends de votre question, c'est que vous voulez copier en profondeur l'objet afin que l'objet d'origine soit intact et que vous puissiez modifier sa copie. Corrigez-moi si je me trompe.

var options=getOptions();

var copyOfObject = JSON.parse( JSON.stringify( options ));
0
mukesh.kumar 11 avril 2018 à 07:59