6
votes

Enregistrement d'exécution et getter dans l'objet JavaScript

Je veux implémenter un setter et un getter sur local variable JavaScript. Voici un exemple de fonction:

function someThing() {
      var someLocalvariable = '';
   this.getLocalvariable = function() {
      return someLocalvariable;
   }
}


0 commentaires

7 Réponses :


2
votes

Douglas Crockford a écrit Ceci sur la mise en œuvre de membres privés dans JavaScript


1 commentaires

meta.stackexchange.com/questions/8231/...



3
votes

quelque chose comme ceci:

function Field(val){
    var value = val;

    this.getValue = function(){
        return value;
    };

    this.setValue = function(val){
        value = val;
    };
}
var field = new Field("test");
field.value
// => undefined
field.setValue("test2")
field.getValue()


0 commentaires

14
votes

Votre dernier exemple de ce que vous ne voulez pas faire ne fonctionnera pas (il contient des erreurs de syntaxe), s> (il a été corrigé) em> mais je pense que vous pouvez Ont signifiait la façon habituelle de le faire, ce qui consiste à effectuer les fermetures de getter et de setter dans la fonction de constructeur (ci-dessous).

Malheureusement, si vous voulez des variables vraiment privées, il s'agit de votre seule option. Il n'y a pas d'autre moyen d'obtenir véritablement em> privé, spécifiques d'instance em> variables. Cependant, voir "Hack" ci-dessous. P>

Voici la version correcte de la manière habituelle de le faire (que je pense que vous avez dit que vous ne voulez pas, mais pour la complétude): P>

var SomeThing = (function() {
    var cache = {}, idAllocator = 0;

    function SomeThing() {
        this.id = ++idAllocator; // The unique identifier, can be a string if desired
        cache[this.id] = {};
    }
    SomeThing.prototype.getPrivateVar = function() {
        var data = cache[this.id];
        return data && data.privateVar;
    };
    SomeThing.prototype.setPrivateVar = function(value) {
        cache[this.id].privateVar = value;
    };
    SomeThing.prototype.destroy = function() {
        delete cache[this.id];
    };

    return SomeThing;
})();


7 commentaires

Il en connaît déjà cependant depuis que c'est dans l'un de ses exemples de ce qu'il ne veut pas faire.


@ THOR84NO: L'exemple dont vous parlez n'est pas en fait ce qui précède, mais je pense que vous avez raison que c'était censé être. J'ai édité pour résoudre ce problème.


La version révisée est très complète. Très bonne réponse.


@TJCrowder: J'ai entendu l'argument contre le premier modèle (I.e. Crockford) en ce qui concerne l'utilisation de la mémoire - et je pense que c'est plausible - mais je n'ai jamais vu pour personne post des tests. Pouvez-vous fournir un lien?


@ FK82: Non, je n'ai jamais vu quelque chose en profilant. Notez qu'il sera incroyablement sensible au moteur JavaScript utilisé, éventuellement la taille des fonctions, etc. Sur un moteur très intelligent, je m'attendrais à ce que les frais généraux soient minimes: fonction multiple objets (qui ne doit pas être aussi coûteux), mais avec le code sous-jacent partagé. Les moteurs moins optimisés peuvent ne pas réutiliser le code parmi les différents objets de fonction (et les objets de fonction ont différent pour que le moteur soit conforme à la spécification; le code sous-jacent est une question différente).


@ T.J. Bonne point de Crowder. Je pensais l'inverse en fait. Ce qui signifie que la fonction s spécifiée dans le prototype devra être instanciée par le moteur JavaScript - lorsque la fonction parent est instanciée - de toute façon parce qu'elles ouvrent chacune une contexte d'exécution individuel. DUNNO Si cela est en fait précis ou non, mais je imo c'est probablement le cas.


@ FK82: La fonction attribuée à un prototype est partagée entre les instances. Si vous avez une fonction de constructeur FOO , et que vous avez une fonction attribuée à foo.pototype.bar , que la même fonction est utilisée par toutes les instances Créé via nouveau foo () . Il n'y a qu'une seule fonction objet pour bar . C'est la raison essentielle de les avoir sur le prototype. En revanche, si vous avez créé une fonction dans l'appel à FOO comme dans le modèle Crockford ci-dessus, une nouvelle fonction sera créée chaque fois que vous appelez nouveau foo () .



2
votes

Ce n'est pas possible. Si vous avez une variable locale dans quelque chose (), la fonction que vous attachez au prototype ne peut pas lire sa valeur (elle est privée, rappelez-vous?). Votre dernier exemple est la solution normale à ce problème, pourquoi n'est-ce pas suffisant pour vous?


0 commentaires

4
votes

Utilisez objet.defineProperty () dans le constructeur de fonctions afin de définir votre getter and Setter Plus d'infos ici ..puce> faire vraiment privé (pas visible à l'extérieur) Certaines valeurs utilisent une fermeture, Plus d'informations peuvent être trouvées ici . p>

Dans l'exemple suivant, nous définissons un getter et un setter pour la propriété Température code>, dans laquelle la valeur "privée" interne est stockée dans une variable la température de var code>. p>

la température var code> ne sera jamais visible / accessible à partir de l'extérieur de archiver () code> est une fermeture. P>

Veuillez noter que ce modèle fonctionne sur ES5 comme objet.defineProperty () il n'est pas pris en charge sur ES3. P>

function Archiver() {
    var temperature = null;
    var archive = [];

    Object.defineProperty(this, 'temperature', {
        get: function () {
            console.log('get!');
            return temperature;
        },
        set: function (value) {
            temperature = value;
            archive.push({ val: temperature });
        }
    });

    this.getArchive = function () {
        return archive;
    };
}

var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]


2 commentaires

Cela semblerait être la meilleure solution maintenant que l'objet.defineProperty existe et vous permet d'utiliser les getters / setters comme si elles étaient des propriétés régulières.


@ Sweaver2112 Oui Vous pouvez voir la table de compatibilité du navigateur à développeur. mozilla.org/fr/docs/web/javascript/reference/...



0
votes

Essayez ces deux façons d'obtenir un réglage et getter xxx


0 commentaires

0
votes

première méthode xxx

seconde méthode xxx


0 commentaires