2012-10-27 3 views
2

est-ce possible?Membre privé sur prototype avec plusieurs instances

Nous savons bien comment imiter les membres privés en javascript:

var Class = (function() { 
    var _private; 

    Class = function() { 
     _private = {}; 
    }; 

    Class.prototype.set = function(name, value) { 
     _private[name] = value; 
    }; 

    Class.prototype.get = function(name) { 
     return _private[name]; 
    }; 

    return Class; 

})(); 

L'effet secondaire de ce modèle est que lorsque je crée deux instances:

var instanceOne = new Class(); 
var instanceTwo = new Class(); 

alors la propriété privée est partagée entre :

instanceOne.set('test', 'me'); 
instanceTwo.get('test'); 

Y at-il une solution à ce problème?

Cordialement

Répondre

3

La méthode standard d'avoir des membres « privés » en JavaScript est d'utiliser des variables locales dans le constructeur et ont tout ce qui a besoin d'y avoir accès définies comme des fermetures dans le cadre de l'appel au constructeur, comme ceci:

function Class() { 
    var privateValue = 0; 

    this.getPrivateValue = function() { 
     return privateValue; 
    }; 
} 
Class.prototype.doSomething = function() { 
    // This function doesn't have access to `privateValue` 
    // except through `getPrivateValue`, even though 
    // it's accessible as a member of the instance 
}; 

cela a été décrit par beaucoup, sans doute le plus célèbre Douglas Crockford.

Notez que cela a pour conséquence que chaque instance de Class obtient son propre copie de la fonction getPrivateValue, parce que chacun est une fermeture sur un autre appel au constructeur (ce qui est la raison pour laquelle cela fonctionne). (Cela ne signifie pas tout le code de la fonction est reproduite, cependant, au moins certains moteurs   — moteur V8 de Google, utilisé dans Chrome et ailleurs, par exemple   — permettent même le code à partager par fonctions multiples

(Note: Je n'ai pas utilisé le nom private parce que c'est un mot réservé Dans ES3, c'était un "futur mot réservé"; dans ES5, c'est un seul dans le strict mode; details.)

J'ai utilisé une simple variable ci-dessus plutôt qu'un objet pour éviter de rendre les choses plus complexes qu'elles ne le sont. Voici la façon dont s'appliquerait à votre exemple:

function Class() { 
    var privateData = {}; 

    this.get = function(name) { 
     return privateData[name]; 
    }; 

    this.set = function(name, value) { 
     privateData[name] = value; 
    }; 
} 

Ou si vous voulez encore aussi ont des données privées de classe à l'échelle partagée entre les instances:

var Class = function() { 
    var dataSharedAmongstInstances; 

    function Class() { 
     var privateDataForEachInstance = {}; 

     this.get = function(name) { 
      return privateDataForEachInstance[name]; 
     }; 

     this.set = function(name, value) { 
      privateDataForEachInstance[name] = value; 
     }; 
    } 

    return Class; 
})(); 
+0

La façon plus commune, également utilisé dans python, est un préfixe de soulignement. Les gens devraient savoir que les fonctions créées dans le constructeur ne sont pas statiques, ce sont des objets uniques pour chaque fonction créée pour chaque instance. – Esailija

+0

@Esailija: Underscore préfixe ne crée pas de membres privés. (Je sais ** vous ** le savez, mais pour quiconque se cache ...) Il crée des membres publics avec des noms commençant par des traits de soulignement, point final. * Les traiter comme privés est entièrement quelque chose que quelqu'un fait dans le code par convention, rien de plus. Et oui, beaucoup de gens le font. Mais parce que la vie privée n'est pas appliquée, les gens vont enfreindre la règle. En fait, je n'ai jamais travaillé avec une base de code significative utilisant cette règle où quelqu'un * ne l'a pas * cassé. Mais cette affirmation trompe un peu, je n'ai travaillé que sur quelques projets en utilisant cette règle. ;-) –

+0

Eh bien, cela ne crée pas non plus de membres privés, ce sont des variables.Ils ne sont traités que comme des membres mais vous ne pouvez rien faire avec eux que les vraies propriétés de l'objet supportent – Esailija

Questions connexes