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 :

Accéder à une variable en JS OO


Sujet :

JavaScript

  1. #1
    Invité
    Invité(e)
    Par défaut Accéder à une variable en JS OO
    Bonjour,

    Dans le script suivant, je n'arrive pas à afficher correctement la variable this.param dans le contexte d'une requête Ajax :

    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
    function MaClasse (variable) {
     
    this.param = variable;
     
    this.open = function () {
    	new Ajax.Request('action.php', {
    		method : 'POST',
    		onSuccess : function(xhr) {				
    		  alert(this.param);
    		});
    	}
    }
     
    var obj = new MaClasse('var_1');
    obj.open();
    Merci d'avance à qui pourra bien m'aider.

    Fabien

  2. #2
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 7
    Par défaut
    Salut,

    L'instruction 'this' référence les propriétés de la fonction dans laquelle l'instruction est jouée.

    Essai ça : alert(this.parent.param)

    Cordialement.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci beaucoup, mais ça ne fonctionne pas. C'est toujours UNDEFINED...

  4. #4
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function(xhr) {				
    		  alert(this.param);
    		}
    fait référence a la méthode et non plus a l'objet , il te faut donc passer en paramètre param

  5. #5
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 7
    Par défaut
    Le problème vient de la portée de la variable param.

    Est-ce que en la déclarant en variable globale, cela fonctionne mieux ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function MaClasse (variable) {
    param = variable;		
    this.open = function () {
    	new Ajax.Request('action.php', {
    		method : 'POST',
    		onSuccess : function(xhr) {				
    		  alert(param);
    		});
    	}
    }
     
    var param;
    var obj = new MaClasse('var_1');
    obj.open();

  6. #6
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 658
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 658
    Billets dans le blog
    1
    Par défaut
    bein entendu avec une variable globale ça passe mais c'est risqué en cas d'instances multiples à moins de pusher un array ...

    je tentais l'opération avec call ou apply , mais a priori ça n'a pas l'air de vouloir
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  7. #7
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    oui ça marche , mais ce n'est pas le but
    donc passe la en closure ( je te renvois vers les tutoriels de la section JS )

  8. #8
    Invité
    Invité(e)
    Par défaut
    Merci à vous, je vais jeter un coup d'œil aux tuts, je reviens vers vous en cas de besoins.

  9. #9
    Invité
    Invité(e)
    Par défaut
    le chomeur, j'ai testé ta méthode, ça fonctionne par contre, je ne peux pas exploiter le contenu de la variable param en dehors de l'objet :

    par exemple, puisqu'il a fallu rempacer :

    par

    De plus si je passe ma fonction open en prototype, comme ceci :

    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
    function MaClasse (variable) {		
    	this.param = variable;
    }
     
    MaClasse.prototype.open = function () {
    	new Ajax.Request('action.php', {
    		method : 'POST',
    		onSuccess : function(xhr) {				
    		  alert(this.param);
    		});
    	}
     
     
    var obj = new MaClasse('var_1');
    obj.open();
    Ça ne fonctionne plus.

    Je débute dans le JSOO avec l'excellent tutoriel de votre site, et j'essaie de mettre à jour des scripts à moi avec cette méthode, avec plus ou moins de réussite.

    Encore merci d'avance.

  10. #10
    Membre expérimenté Avatar de nod__
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    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
    function MaClasse (variable) {
    var that = this;
     
    this.param = variable;
     
    this.open = function () {
    	new Ajax.Request('action.php', {
    		method : 'POST',
    		onSuccess : function(xhr) {				
    		  alert(that.param);
                     // mais c'est naze autant passer "variable" directement à ta fonction…
    		});
    	}
    }
     
    var obj = new MaClasse('var_1');
    obj.open();
    ton "this" correspondait à l'objet que tu passes en paramètre à "Ajax.Request". pas à ce que tu pensait.

    Petite précision ce n'est pas une classe que tu définit, c'est un constructeur. Les classes n'existent pas en javascript (et c'est très bien comme ça), c'est juste une vue de l'esprit erroné.

  11. #11
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    Pour que this représente bien ton instance dans un callback
    tu peux utiliser ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Function.prototype.bind = function(context) {
      var m = this; // référence l'instance de Function
      return function() {
        return m.apply(context, arguments);
      }
    }
    Ici on définit une méthode propre à l'objet Function en l'ajoutant
    à son prototype, toutes les instances de Function existantes ou
    futures disposent de la méthode bind, c'est à dire, toutes les
    fonctions javascript en général.

    Cette méthode sauve this dans une variable m (this représentant l'instance
    de la fonction sur laquelle on appelle bind), puis elle retourne une fonction
    interne qui appelle l'instance originale de la fonction "bindée" via apply,
    ce qui permet de fixer le context du this pour le code de la fonction à ce
    que l'on souhaite.

    le paramètre context est visible de la fonction interne grâce à une closure.

    A l'usage cela devient assez simple:

    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
    function MaClasse (variable) {
     
    this.param = variable;
     
    this.open = function () {
    	new Ajax.Request('action.php', {
    		method : 'POST',
    		onSuccess : function(xhr) {				
    		  alert(this.param);
    		}.bind(this));
    	}
    }
     
    var obj = new MaClasse('var_1');
    obj.open();
    Mais je pense qu'utiliser javascript pour produire du code 'genre POO'
    c'est passer à coté d'une autre forme de programmation pour laquelle
    javascript est bien plus adapté (je pense aux closures et imbrication de
    callbacks)

    Dans ce goût là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function faireQqch(param1) {
        AjaxRequest('action1.php', {...}, function(reponse1) {
            var x = ...;
            // traiter la réponse 1
            AjaxRequest('action2.php', {...}, function(reponse2) {
                // traiter la réponse 2
            });
        });
    }
    Ici dans le contexte de la fonction callback(reponse2) nous
    avons accès à toutes les variables des fonctions englobantes
    param1, reponse1, reponse2, x

    En englobant ainsi, le simple appel à faireQqch crée une forme
    d'instance avec ses variables propres.

    De plus l'indentation donne une idée de l'ordre d'exécution des
    fonctions dans le temps.

    Dans le cas typique des appels et traitement Ajax je trouve
    cette manière de coder plus légère que le POO like. (le débat
    est ouvert :-)

  12. #12
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    c'est ce que je disais , un passage de paramètre en closure , ou via une fonction anonyme ;-)

    interessant la méthode de binding marcha , je l'utilisais pour gérér des variable dans des boucles ( les fameux for(){} avec i lié a un instant T )

  13. #13
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Citation Envoyé par le_chomeur Voir le message
    les fameux for(){} avec i lié a un instant T
    qu'est-ce ? ça semble intéressant tu peux détailler ?

  14. #14
    Membre Expert Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Par défaut
    Par ailleurs, vu que tu utilises visiblement la librairie prototype, tu devrais jeter un oeil à la méthode bindAsEventListener qui fait a peu près la même chose que la méthode proposée par marcha mais dans l'api prototype.

  15. #15
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    alors dans l'ordre un exemple de closure sans utiliser de bind :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var me = this;
    				var action = function(){(function(){
    					me.yearsBefore();
    				})(me)};

    et un exemple un peu plus complet pour comprendre le fonctionnement :

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    		<title>Untitled Document</title>
    	</head>
    	<body>
     
     
    		<a href="#">test</a><br />
    		<a href="#">test</a><br />
    		<a href="#">test</a><br />
    		<a href="#">test</a><br />
    		<a href="#">test</a><br />
    		<a href="#">test</a><br />
    		<input type="button" onclick="test2()" value="test avec la fonction 2" />
    		<script type="text/javascript">
    			function test1(){
    				var ListeLien = document.getElementsByTagName("a");
    				for(var i = 0 , l = ListeLien.length; i < l ; i++){
    					var t = i ;
    					ListeLien[i].onclick = function(){alert(t);return false;};
    				}
    			}
    			test1();
     
    			function test2(){
    				var ListeLien = document.getElementsByTagName("a");
    				for (var i = 0, l = ListeLien.length; i < l; i++) {
     
    					var action = function(){
    						var t = i ;
    						return function(){
    							alert(t)
    						};
    					}(i);
     
    					ListeLien[i].onclick = action;
    				}
    			}
    		</script>
    	</body>
    </html>
    on peut passer un paramètre à la deuxiemme méthode , mais ce sera l'évènement.

  16. #16
    Membre expérimenté Avatar de nod__
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    oui enfin pour les boucles autant utiliser les trucs standards, c'est a dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    monArray = [];
    monArray.forEach(function (valeur, index, tableau) {});
    On peut l'utiliser dans IE et les autres en augmentant le prototype de l'objet Array (normalement, j'ai pas IE pour retester) ou au moins ajouter la méthode (qui existe sous Mozilla) à l'objet Array. Voir la doc pour les détails.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    monArray = [];
    Array.forEach(monArray, function (valeur, index, tableau) {});
    La closure est faite toute seule et c'est du JS standard. Mieux que du bricolage

  17. #17
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    tu peux expliciter ? un exemple concret ??
    avec une variable incrémenté

  18. #18
    Membre expérimenté Avatar de nod__
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                function test2(){
                    var ListeLien = document.getElementsByTagName("a");
     
                    Array.forEach(ListeLien, function (lien, index) {
                        lien.onclick = function () {alert(index);};
                    });
                }
    A tester sous FF bien évidement. Ça peut être implémenté facilement pour les autres

  19. #19
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Par défaut
    Sous FF ;-) mais ne marche pas sous IE and cie

  20. #20
    Membre expérimenté Avatar de nod__
    Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2009
    Messages : 176
    Par défaut
    oui mais je viens de te dire que ça s'implémente facilement sous IE et Co. Ça fait (ou va très bientôt faire) parti de la spec Ecmascript donc bon…

Discussions similaires

  1. [Eclipse RCP] accéder à une variable globale
    Par fabrisss dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 10/01/2007, 08h37
  2. Réponses: 4
    Dernier message: 13/12/2006, 16h10
  3. accèder une $variable en bas de page !
    Par Dsphinx dans le forum Langage
    Réponses: 11
    Dernier message: 24/11/2006, 10h23
  4. accéder à une variable déclarée dans un autre fichier
    Par sg.forums dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 31/10/2006, 09h20
  5. [PERL] accéder à une variable d'une autre classe
    Par LE NEINDRE dans le forum Langage
    Réponses: 8
    Dernier message: 11/01/2006, 17h06

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