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 éprouvé 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
    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
    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 confirmé
    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 : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    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.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  4. #4
    Membre éprouvé 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
    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
    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 éprouvé 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
    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