Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire : Cours JavaScript, FAQ JavaScript, Toutes les FAQ JavaScript et Sources JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/09/2011, 11h37   #1
Membre confirmé
 
Inscription : septembre 2005
Messages : 801
Détails du profil
Informations forums :
Inscription : septembre 2005
Messages : 801
Points : 202
Points : 202
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 :
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.
Blaise1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 12h47   #2
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
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 :
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é.
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 12h49   #3
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
Au lieu de faire une méthode pseudo-statique "Create", utilise plutôt un constructeur.
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 14h50   #4
Membre régulier
 
Inscription : octobre 2010
Messages : 65
Détails du profil
Informations forums :
Inscription : octobre 2010
Messages : 65
Points : 87
Points : 87
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++ :
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# :
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.
p3ga5e est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 16h59   #5
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
@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.
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/09/2011, 21h18   #6
Membre régulier
 
Inscription : octobre 2010
Messages : 65
Détails du profil
Informations forums :
Inscription : octobre 2010
Messages : 65
Points : 87
Points : 87
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 ^^
p3ga5e est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 09h59   #7
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
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
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 16h52   #8
Membre régulier
 
Inscription : octobre 2010
Messages : 65
Détails du profil
Informations forums :
Inscription : octobre 2010
Messages : 65
Points : 87
Points : 87
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 :
1
2
3
4
div.onmousedown = function(obj)
{
    return function(){  obj.onDivMouseDown(); }
}(this);
p3ga5e est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/09/2011, 18h31   #9
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
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
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 13h17   #10
Membre confirmé
 
Inscription : septembre 2005
Messages : 801
Détails du profil
Informations forums :
Inscription : septembre 2005
Messages : 801
Points : 202
Points : 202
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
Blaise1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 13h39   #11
Membre éclairé
 
Homme
F5(){F5}
Inscription : avril 2008
Messages : 256
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : F5(){F5}
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : avril 2008
Messages : 256
Points : 320
Points : 320
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.
galerien69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h53.


 
 
 
 
Partenaires

Hébergement Web