102 votes

JavaScript: Comment passer objet par valeur?

  • Lors du passage d'objets comme paramètres, JavaScript passe par référence et rend difficile de créer des copies locales des objets.

    var o = {};
    (function(x){
        var obj = x;
        obj.foo = 'foo';
        obj.bar = 'bar';
    })(o)
    

    o sera .foo et .bar.

  • Il est possible de contourner ce problème par clonage; exemple simple:

    var o = {};
    
    function Clone(x) {
       for(p in x)
       this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p];
    }
    
    (function(x){
        var obj = new Clone(x);
        obj.foo = 'foo';
        obj.bar = 'bar';
    })(o)
    

    o n'aura pas d' .foo ou .bar.


Question

  1. Est-il un meilleur moyen de passer les objets par valeur, autres que la création d'une copie locale/clone?

65voto

user113716 Points 143363

Pas vraiment.

En fonction de ce que vous avez réellement besoin, une possibilité peut-être de fixer o comme le prototype d'un nouvel objet.

var o = {};
(function(x){
    var obj = Object.create( x );
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o);

alert( o.foo ); // undefined

Donc toutes les propriétés que vous ajoutez à l' obj sera pas ajoutée o. Toutes les propriétés ajoutées obj avec le même nom de la propriété à la propriété en o fera de l'ombre à l' o de la propriété.

Bien sûr, toutes les propriétés ajoutées o sera disponible à partir de obj s'ils ne sont pas occultées, et tous les objets qui ont o dans la chaîne de prototype permettra de voir les mêmes mises à jour de o.

Aussi, si obj a une propriété qui fait référence à un autre objet, comme un Tableau, vous aurez besoin pour être sûr d'ombre de l'objet avant de l'ajout de membres à l'objet, par ailleurs, les membres seront ajoutés obj, et sera partagé entre tous les objets qui ont obj dans la chaîne de prototype.

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // 'new_value'

Vous pouvez voir ici que parce que vous n'avez pas d'ombre au Tableau lors de la baz sur o avec un baz bien sur obj, l' o.baz Tableau se modifie.

Donc, au lieu de cela, vous auriez besoin de l'ombre en premier:

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz = [];
    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // undefined

55voto

svimre Points 106

Découvrez cette réponse http://stackoverflow.com/a/5344074/746491 .

En bref, JSON.parse(JSON.stringify(obj)) est un moyen rapide de copier vos objets, si vos objets peuvent être sérialisés en json.

43voto

Paul Varghese Points 558

Voici la fonction clone qui va cloner l'objet.

 function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor(); 
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}
 

Maintenant, vous pouvez utiliser comme ceci
(fonction (x) {var obj = clone (x); obj.foo = 'foo'; obj.bar = 'bar';}) (o)

17voto

Andy E Points 132925

Vous êtes un peu confus au sujet de comment fonctionnent les objets en JavaScript. La référence de l'objet est la valeur de la variable. Il n'y a pas de désérialisation valeur. Lorsque vous créez un objet, sa structure est stocké dans la mémoire et la variable qui lui a été assigné contient une référence à cette structure.

Même si ce que vous demandez a été fourni dans une sorte de facile, la langue maternelle construire, il serait toujours techniquement possible de clonage.

JavaScript est vraiment juste passer-par-valeur... c'est juste que la valeur passée pourrait être une référence à quelque chose.

8voto

Brett Weber Points 775

Une question pour les utilisateurs de jQuery, il est aussi un moyen de faire cela de façon simple, en utilisant le framework. Juste une autre façon de jQuery fait de notre vie un peu plus facile.

var oShallowCopy = jQuery.extend({}, o);
var oDeepCopy    = jQuery.extend(true, {}, o); 

références :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X