IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[Objet] Accès à propriété privée depuis méthode statique


Sujet :

JavaScript

  1. #1
    Invité
    Invité(e)
    Par défaut [Objet] Accès à propriété privée depuis méthode statique
    Bonjour à tous,

    Je me demande s'il est possible, depuis une méthode statique, d'accéder à une propriété privée d'un objet.
    J'ai une méthode statique qui doit être utilisée pour créer et persister un objet. En retour, j'attends l'objet crée avec toutes ses propriétés dont son identifiant (créé lors de la persistance). Cet identifiant n'étant pas modifiable, je le veux uniquement en lecture. Ce qui pose problème dans ma méthode de création. Mais je me dis qu'il est peut-être possible au sein d'une méthode statique d'accéder à une propriété privée étant donné qu'ils appartiennent au même objet...

    Un peu de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function Person(firstName, lastName) {
     
    	var _id;
    	var _firstName = firstName;
    	var _lastName = lastName;
     
    	this.getId = function() {
    		return _id;
    	}
     
    	this.getFisrtName = function() {
    		return _firstName;
    	}
     
    	this.toString = function() {
    		return _firstName+' '+_lastName;
    	}
    }
     
    Person.Create = function(firstName, lastName) {
            var rep = // Appel ajax au service qui renvoie les propriétés dans "rep"
    	var created = new Person(rep.firstName, rep.lastName);
    	created._id = rep.id;
    	return created;
    }
    Or, lorsque j'affiche created.id j'obtiens "undefined"...

    Merci pour votre aide.

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Par défaut
    Nop, impossible. Même dans un langage autre que JS tu ne pourrais pas d'ailleurs.

    Le concept des variables privées c'est qu'elle contiennent des informations relatives à l'état interne (puisque privé) de ton objet. C'est totalement dépendant de ton instance, donc tes méthodes statiques n'ont rien à faire avec !

    Pour faire simple, en Javascript ton scope est lexical :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    A{
       var private = true;
     
       B{
           alert(private); // true
       }
    }
    C{
       alert(private); // undefined
       alert(A.private); // undefined
    }
    Donc il est totalement impossible d'avoir un membre statique accedant à un membre privé.

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Par défaut
    Au lieu de faire une méthode pseudo-statique "Create", utilise plutôt un constructeur.

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Par défaut
    Citation Envoyé par TheGwy Voir le message
    Nop, impossible. Même dans un langage autre que JS tu ne pourrais pas d'ailleurs.
    En faite dans d’autre langage Objet a base de class tel que c++, ou C# c’est possible :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class CPerson
    {
    private :
    	int m_id;
    	CPerson(void){}
     
    public:
    	~CPerson(void){}
     
    	static CPerson* Create()
    	{
    		CPerson* p = new CPerson();
    		p->m_id = 100;
    		return p;
    	}
    };
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Person
    {
        private Guid m_id;
     
        public static Person Create()
        {
            Person p = new Person();
            p.m_id = Guid.NewGuid();
            return p;
        }
    }

    Le problème est que le hack utilisé par Blaise1, pour utiliser des membres privés, est vraiment a éviter, car tes variables _id, _firstName et _lastName ne sont pas encapsulés dans l’objet Person. Ils sont accessiblent uniquement dans les méthodes déclarés dans la fonction "constructeur".

    Blaise1, je te déconseille cet méthode de déclaration, car tes objets ce limiteront a un simple hashtable de fonctions, et tu ne pouras pas utilisé des fonctions générique utilisant la réflexivité d’objet, comme par exemple des methodes de sérialisation d'objet.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Par défaut
    @p3ga5e : au temps pour moi, je ne suis pas du tout fluent en C/C++

    Pour ce qui est de ta remarque, je ne serai pas si catégorique.

    Utiliser des closures comme il le fait à ce désavantage : illusion d'une visibilité "private" (ou encapsulation à l'instance de l'objet), alors que ce n'est qu'une visibilité lexicale; donc les méthodes d'instance doivent être dupliquées pour chaque instance si elles ont besoin d'accéder aux propriétés de l'instance.

    Mais elles ont un avantage énorme qui est d'offrir une vraie protection en lecture. Ce qui est très important si tu fais du mashup, ou si tu dois maintenir du code sur la durée sur lequel beaucoup de devs sont susceptibles d'intervenir.

    Pour ce qui est de chose comme la sérialisation cela peut toujours être résolu assez proprement avec une méthode d'instance serialize() qui elle aura accès au scope.

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Par défaut
    tu sous-entend que c'est une pratique largement utilisé par les web developpeurs ?
    vous n'encapuslez dans l'objet que les referance aux methodes et pas les données ?
    etrange ! je suis pas sure que l'on puissent encore appeler ca un objet si celui-ci ne contient pas de données

    pour information les compilateurs c++ font le contraire, le new sur un objet retourne une adresse sur allocation memoire contenant uniquement les données
    les adresses sur les méthodes de l'objet sont contenus dans une structure , la VirtualTable, se trouvant a proximité mémoire de la référence sur l'objet, son emplacement depend du compilateur et elle n'est, normalement, pas accessible au developpeur c++
    L'accessibilité au données membre sont, elles, verifiés uniquement a la phase de compilation.

    Citation Envoyé par TheGwy Voir le message
    Mais elles ont un avantage énorme qui est d'offrir une vraie protection en lecture
    j'ai du mal a comprendre en quoi l'avantage est énorme par raport a la perte d'encapsulation des données, qui elle, est un désavantage énorme ... en meme temps je n'ai jamais bosser en combinaison avec différentes équipes de développement.

    Citation Envoyé par TheGwy
    Pour ce qui est de chose comme la sérialisation cela peut toujours être résolu assez proprement avec une méthode d'instance serialize() qui elle aura accès au scope.
    Si tu trouve ca propre je te conseille de te mettre aux C++, les architectures de logiciel en c++ sont souvent sur ce modèle la, bien que le c++ permet le développement générique avec les types template.
    Personnellement je trouve rien de plus fustrant que de subir ce type d'architecture lorsque l'on utilise un langague supportant la réflexivité, surtout si cet restriction est liée a un simple problème d'accessibilité aux données membres
    Sérieusement ce type d'architecture est moins productif, moins évolutif qu'une approche générique, pretendre le contraire relève du pur masochisme ^^

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Par défaut
    Citation Envoyé par p3ga5e Voir le message
    tu sous-entend que c'est une pratique largement utilisé par les web developpeurs ?
    vous n'encapuslez dans l'objet que les referance aux methodes et pas les données ?
    etrange ! je suis pas sure que l'on puissent encore appeler ca un objet si celui-ci ne contient pas de données
    Hein quoi ?! J'ai jamais dis ça.

    Citation Envoyé par p3ga5e Voir le message
    j'ai du mal a comprendre en quoi l'avantage est énorme par raport a la perte d'encapsulation des données, qui elle, est un désavantage énorme ... en meme temps je n'ai jamais bosser en combinaison avec différentes équipes de développement.
    Bah non tu ne pers pas l'encapsulation, au contraire c'est le seul moyen d'en avoir en Javascript.


    /me pense qu'on a des problèmes de communication tout les deux

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Par défaut
    Si on parle bien, tous deux, des déclarations _id, _firstName et _lastName dans la fonction "constructeur" Person, alors ces données ne sont absolument pas encapsulés dans l’objet retourné par l’operateur new. Pour qu’elles le soient il faut les ajoutées a l’objet en cours de construction en préfixant les déclarations par this. Le faite que ces déclarations soit accessibles dans les méthodes de l’objet ne nous permet pas d’en déduire qu’elles soient encapsulé dans l’objet, c’est une mécanique de portée des variables "local" d’une fonction, qui est bien plus général, que la mécanique de prototypage d’objet.

    Si je me trompe pas le terme "closure" en javascript désigne une technique permettant de capturé la valeur d’un variable, local a une fonction "père", en déclarant une fonction anonyme et en l’exécutant dans la foulée, un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    div.onmousedown = function(obj)
    {
        return function(){  obj.onDivMouseDown(); }
    }(this);

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Par défaut
    Citation Envoyé par p3ga5e Voir le message
    Si on parle bien, tous deux, des déclarations _id, _firstName et _lastName dans la fonction "constructeur" Person, alors ces données ne sont absolument pas encapsulés dans l’objet retourné par l’operateur new. Pour qu’elles le soient il faut les ajoutées a l’objet en cours de construction en préfixant les déclarations par this. Le faite que ces déclarations soit accessibles dans les méthodes de l’objet ne nous permet pas d’en déduire qu’elles soient encapsulé dans l’objet, c’est une mécanique de portée des variables "local" d’une fonction, qui est bien plus général, que la mécanique de prototypage d’objet.
    Oui c'est exactement ce que je disais dans mon premier message "illusion d'une visibilité "private" (ou encapsulation à l'instance de l'objet), alors que ce n'est qu'une visibilité lexicale".

    Après cela reste malgré tout une encapsulation, certes lié à un scope plutôt qu'à ton objet, mais si tu en es conscient cela ne cause aucun problème. Tu peux même te servir de cette subtilité à ton avantage.
    Tandis qu'utiliser "this" contrairement à ce que tu dis ne permet pas de faire d'encapsulation, mais d'attribuer une propriété qui sera toujours visible depuis l'extérieur ! CQFD.

    Citation Envoyé par p3ga5e Voir le message
    Si je me trompe pas le terme "closure" en javascript désigne une technique permettant de capturé la valeur d’un variable, local a une fonction "père", en déclarant une fonction anonyme et en l’exécutant dans la foulée, un truc du genre :
    Oui, ton exemple est valide, mais très restrictif. Une closure c'est beaucoup plus global comme concept, grosso modo c'est le fait de créer un contexte qui n'est pas accessible depuis l'espace global et non garbage collectable car tu as un objet fonction dont le Variable Object à une référence vers le Variable Object parent.

    PS : je n'ai toujours pas compris le pourquoi de ton message précédent

  10. #10
    Invité
    Invité(e)
    Par défaut
    Ok, merci beaucoup pour toutes vos réponses.

    Mais alors, concrètement, je fais quoi, comment est-ce que j'écris mon objet ?
    En sachant que veux garder cette méthode statique de création (qui feras un appel Ajax etc.. en plus de l'appel au constructeur)

    Merci

  11. #11
    Invité
    Invité(e)
    Par défaut
    salut,

    pourquoi ne pas passer tout simplement l'id au constructeur?

    parce que bon, si tu instancies une personne, t'as un id undefined...
    Donc si tu supposes que tu dois automatiquement passer par Person.create, alors c'est pas gênant de mettre tous les arguments nécessaires dans le constructeur de Person, vu que Person.create se porte garant d'instancier correctement la personne.

Discussions similaires

  1. Accès variable privée depuis fonction callback
    Par WildInTheWoods dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 14/01/2011, 10h18
  2. Accès à form1 depuis méthode statique
    Par atoutsweb dans le forum Windows Forms
    Réponses: 10
    Dernier message: 15/04/2009, 09h32
  3. Réponses: 5
    Dernier message: 18/09/2008, 17h20
  4. ArrayList accès propriété de l'objet
    Par missmarion dans le forum C#
    Réponses: 4
    Dernier message: 29/05/2007, 09h35
  5. [Jscript]Cet objet ne gère pas cette propriété ou cette méthode
    Par 1tox dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 02/06/2006, 09h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo