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 :

Le this dans une fonction privée


Sujet :

JavaScript

  1. #1
    Membre habitué Avatar de GalliezB
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2013
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 89
    Points : 162
    Points
    162
    Par défaut Le this dans une fonction privée
    Bonjour,

    J'aimerai avoir accès à des attributs de mon objet dans une fonction privé qui est dans une de me méthodes.

    Mon constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var affImg = function(s,sX,sY,w,h,x,y){
     
        this.img = new Image();
        this.img.src = s;
     
        this.srcX = sX;
        this.srcY = sY;
        this.width = w;
        this.height = h;
        this.posx = x-this.width/2;
        this.posy = y-this.height/2;
    }
    Mon problème :
    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
     
    affImg.prototype.move = function(){
     
        var sensX=3;
        var sensY=3;
     
        this.posx+=sensX;
        this.posy+=sensY;
     
        var resetPosition = function(){
            this.posx=-50;
            this.posy=-50;
     
            sensX=Math.random();
            sensY=Math.random();
     
        }
     
        if ( this.posx > windowWidth || this.posy > windowHeight){
            resetPosition();
            console.log(this.posx+' et '+this.posy+' et '+sensX+' et '+sensY);
        } else if ( this.posx < -50 || this.posy < -50 ){
     
        }
     
    }
    Ceci va évidemment me poser un problème car this.posx et this.posy ( ligne 11 et 12 ) ne sont pas les même que ceux 4 lignes plus haut ( ligne 7 et 8 ).

    Je pourrai très bien solutionner mon problème rapidement en rendant le tout non privé 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    affImg.prototype.move = function(){
     
        var sensX=3;
        var sensY=3;
     
        this.posx+=sensX;
        this.posy+=sensY;
     
        this.resetPosition = function(){
            this.posx=-50;
            this.posy=-50;
     
            sensX=Math.random();
            sensY=Math.random();
     
        }
     
        if ( this.posx > windowWidth || this.posy > windowHeight){
            this.resetPosition();
            console.log(this.posx+' et '+this.posy+' et '+sensX+' et '+sensY);
        } else if ( this.posx < -50 || this.posy < -50 ){
     
        }
     
    }
    Mais mon but étant d'apprendre, j'aimerai garder cette fonction privé puisqu'elle n'a aucune utilité ailleurs.
    Mon but étant de pouvoir réussir à créer de jolies codes orientés objets en définissant bien ce qui est privé de publique.

    Mais dans ce genre de cas, comment accéder à this.posx dans ma fonction privé ?

  2. #2
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Question vocabulaire je préfère parler de portée de variable/fonction plutôt que méthodes privées/publiques. Tandis qu'en Java, on sépare simplement private, public et protected, en JavaScript on peut déclarer autant de scopes que l'on veut avec les fermetures (closures). Donc ce n'est pas tout à fait la même chose.

    Pour ton problème, la solution la plus simple est de garder une référence à this dans le constructeur comme variable locale :

    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
    affImg.prototype.move = function(){
     
        var sensX=3;
        var sensY=3;
     
        this.posx+=sensX;
        this.posy+=sensY;
     
        var instance = this;
     
        var resetPosition = function(){
            instance.posx=-50;
            instance.posy=-50;
     
            sensX=Math.random();
            sensY=Math.random();
     
        }
     
        if ( this.posx > windowWidth || this.posy > windowHeight){
            resetPosition();
            console.log(this.posx+' et '+this.posy+' et '+sensX+' et '+sensY);
        } else if ( this.posx < -50 || this.posy < -50 ){
     
        }
     
    }
    Une solution un poil plus poussée et moins bien supportée est Function.prototype.bind :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var resetPosition = (function(){
            this.posx=-50;
            this.posy=-50;
     
            sensX=Math.random();
            sensY=Math.random();
     
        }).bind(this);

  3. #3
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    En JavaScript, le this est dynamiquement lié. Grossièrement, cela signifie que l'objet incarné par this est celui qui est « devant le point » lors de l'appel.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monObjet.fairedesTrucs(); // dans cet appel à `faireDesTrucs`, this sera `monObjet`
    S'il n'y a rien devant le point, this est alors window. C'est ce qui se passe quand tu appelles resetPosition();.

    Il y a plusieurs solutions. L'une d'elles, c'est de faire une liaison explicite (en anglais explicit binding). Les fonctions JavaScript ont deux méthodes pour ça (oui, des méthodes de fonctions ça existe ) : call et apply. La différence réside dans la façon de passer les paramètres.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    maFonction.call(contexte, arg1, arg2, etc.)
    maFonction.apply(contexte, tableauDArguments);
    Quand il n'y a pas de paramètres, les deux marchent pareil. Un exemple avec call :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    resetPosition.call(this);
    De cette façon, le this courant (ton instance de affImg) est explicitement lié lors de cet appel à resetPosition. Tu peux vérifier en rajoutant une instruction de débogage dans le corps de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function resetPosition() {
        console.debug("this = ", this);
        ...
    }

    Une autre solution c'est celle de Sylvain : sauvegarder le contexte dans une variable locale, et d'utiliser cette variable à la place de this. J'ai souvent vu des gens nommer cette variable that :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        var that = this;
        var resetPosition = function() {
            that.posx = -50;
            that.posy = -50;
            ...
        };
    Quant au bind, effectivement c'est une méthode récente et donc pas encore bien supportée. En revanche call et apply font partie du cœur de JavaScript.

  4. #4
    Membre habitué Avatar de GalliezB
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2013
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 89
    Points : 162
    Points
    162
    Par défaut
    SylvainPV :

    J'avoue que j'aurai du y penser, simple et efficace. J'vais tester ça.

    Watilin :

    Cool, je comprends beaucoups mieux l'histoire du call et apply. Ma POO est issu de http://t-templier.developpez.com/tut...vascript-poo1/ et j'avais pas bien compris ce concept.

    Va falloir que je test avec des paramètres pour voir la différence.


    Merci à vous !

  5. #5
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Exact, j'avais oublié la solution call/apply. Le seul inconvénient de cette solution, c'est qu'il faut se rappeler de le faire à tous les appels.

    Sinon, j'ai trouvé un polyfill pour Function.bind qui utilise apply:
    https://developer.mozilla.org/en-US/...#Compatibility

  6. #6
    Membre habitué Avatar de GalliezB
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2013
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 89
    Points : 162
    Points
    162
    Par défaut
    Merci pour le polyFill mais je suis pas fan de ce genre d'utilisation tant que je comprends pas parfaitement tout le javascript de base.

    J'aime bien ton http://syllab.fr/projets/web/exposejs/#1

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. this dans une fonction anonyme
    Par Paul TOTH dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 11/01/2012, 13h23
  2. [Dojo] Portée de "this" dans une fonction
    Par Zineb1987_UNI dans le forum Bibliothèques & Frameworks
    Réponses: 8
    Dernier message: 21/12/2009, 17h08
  3. Utilisez MinimizeName() dans une fonction
    Par James_ dans le forum C++Builder
    Réponses: 7
    Dernier message: 07/05/2004, 18h05
  4. [Postgresql]Connecter à une autre base dans une fonction
    Par alex2205 dans le forum Requêtes
    Réponses: 2
    Dernier message: 05/05/2003, 11h30
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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