Comment émuler des membres privés en Javascript

Comme vous le savez, tous les membres d’un objet sont publics en Javascript. Il n’existe aucun moyen de définir une variable comme étant privée ou protégée.

Pourtant, dans certains cas, il peut être utile, voire nécessaire, de garder privé certaines variables, par exemple lorsqu’on développe une librairie destinée à être utilisée par des tiers.
Dans son excellent petit livre Javascript, the Good parts, Douglas Crockford, le père de JSON, nous explique la bidouille pour en mimer le comportement:

var o = function(){
    var _my_private_var = "I am private";
    return {
        test: function(){
            alert("I am a plublic method, having access to a private var: " + _my_private_var);
        }
    }
}();
 
o.test(); // will display the message

Le truc est d’utiliser une fonction anonyme pour définir notre objet.

En Javascript, les fonctions sont des clôtures, ce qui implique qu’elles contiennent une référence au contexte dans lequel elles ont été créés et peuvent y accéder.

La deuxième chose à savoir est que, contrairement par exemple au C, où le scope est défini par block, Javascript définit son contexte par fonction. Si l’on définit une fonction enfant au sein d’une fonction parent, la fonction enfant aura accès aux variables définies dans le parent.

Enfin, afin d’empêcher de retrouver notre variable privée, on utilise une méthode anonyme qu’on exécute directement (cf the « }() » à la fin) pour retourner notre objet.

Du coup, voici ce qui se passe lorsque nous appelons notre méthode test(). La fonction test embarque avec elle une référence au contexte où elle a été créée. Dans notre cas, il s’agit de la méthode anonyme. Elle a donc accès aux variables qui y étaient définies et donc à _my_private_var.

D’un autre côté, nous n’avons pas stocké de référence à la fonction anonyme. L’objet o est le résultat de la fonction anonyme. Nous n’avons donc plus de moyen d’accéder à _my_private_var directement.
Notez que si nous avions enregistré une référence à la fonction, comme les fonctions sont aussi des objets en Javascript, il aurait été possible d’atteindre _my_private_var.

var func = function(){
    var _my_private_var = "I am not that private";
};
alert(func._my_private_var); // Will display "Im am not that private"
  1. Aucun commentaire pour l'instant

  1. Aucun trackback pour l'instant