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 :

Variable d'instance


Sujet :

JavaScript

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 182
    Points : 268
    Points
    268
    Par défaut Variable d'instance
    Bonjour j'ai un travaux pratique à remettre, je me suis dit pftttt javascript, le probleme c'est que faire du simili orienté objet semble plus déroutant que je ne l'aurai imaginé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function Card(img){
     
    	this.img = new Object(img);
    	this.faceDown = true;	
     
     
    	Card.prototype.explode = function() {	
    	if(this.faceDown){
    		$($(img)).hide("explode", { pieces: 35}, 1000).attr("src", "images/1.png").show("explode",{ pieces: 35}, 1000);
    		}
    	}
    }
    j'apelle la fonction explode, la ligne jquery fonctionne très bien, par contre this.faceDown est undefined...

    comment je peut accèder une variable d'instance à partir d'une de ces propres fonctions ?

    apres 100 essaies de syntaxes différentes je n'arrive pas a accéder à faceDown... j'imagine que la variable n'est pas vraiment initilialiser ou quelque chose... comment je peux faire aider moi svp

    merci d'avance...

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    faire du simili orienté objet
    Du simili orienté objet ?
    JavaScript est un langage entièrement orienté objet et il n'y a rien de simili là-dedans... Il n'y a pas que l'orienté objet par classes dans la vie...

    Concernant ton code, déjà, c'est assez maladroit d'augmenter le prototype dans le constructeur, on préfèrera écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function Card(img){
     
    	this.img = new Object(img);
    	this.faceDown = true;
    }	
     
    Card.prototype.explode = function() {	
    	if(this.faceDown){
    		$($(img)).hide("explode", { pieces: 35}, 1000).attr("src", "images/1.png").show("explode",{ pieces: 35}, 1000);
    	}
    }
    Ensuite, comment appelles-tu ce code ?
    As-tu bien créé une instance de ton objet ?
    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var myCard = new Card();
    myCard.explode();
    Enfin
    Comment dire... lol !

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 182
    Points : 268
    Points
    268
    Par défaut
    Merci de ta réponse et...

    désolé pour le
    je devais convertir mon objet DOM en jquery lol.

    D'accord jai compris sa fonctionne pas tout a fait comme dans les languages avec des classes, je ne fait qu'une methode constructeur dans le vide avec mes variables à initialiser et ensuite mes methodes relié à mon objet ne sont que des blocs function completement separé du constructeur. Il n'y a pas d'imbriquation je pensais que le constructeur servais de classe en quelque sorte...

    j'initialise dynamiquement sans nommage: new Card()
    merci pour tes precisions, je refusais de faire du code spagetthi pour mon TP meme si sa ne fait que 2 mois que j'ai commencé l'école et qu'on a pas vu l'orienté objet.

    désolé si j'en ai offusqué certain en disant que javascript était du simili orienté-objet

  4. #4
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    désolé si j'en ai offusqué certain en disant que javascript était du simili orienté-objet
    Oh rassure-toi, tu n'es pas le seul à penser cela et je doute que tu t'aies fait cette opinion par toi-même...
    Toujours est-il qu'une opinion trop souvent répandue et à tort veut que JavaScript soit un mauvais langage sans modèle objet.
    Que JavaScript ne soit pas parfait, tout le monde en convient, mais qu'il n'ai pas de modèle objet est une aberration : encore une fois, ce n'est pas un modèle par classes, mais c'est un modèle objet à part entière quand même et tout aussi puissant.

    Bon, il serait trop long et fastidieux de revenir sur tous les aspects de la POO en JavaScript (constructeur vs objet littéral par exemple ou méthode d'objet vs prototype sans parler des notions d'héritage ou de visibilité des variables).

    Toujours est-il qu'un objet possède toujours un prototype, qui est indépendant de l'objet lui-même, c'est pourquoi il est plus propre de le définir à part. Ce prototype est lui même un objet, tu peux donc l'affecter en une fois comme tel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Card.prototype = {
        methode1: function(){...},
        methode2: function(){...},
        methode3: function(){...}
    };
    ou comme je l'ai fait en définissant des propriétés individuellement (méthode utile pour augmenter un prototype existant).

    Ensuite, pour se servir de cet objet, il faut en créer une instance (comme en PHP du reste...)

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 182
    Points : 268
    Points
    268
    Par défaut
    Merci pour toute ces precisions, mais jai encore un petit soucis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    function Card(faceDown){
    this.faceDown = faceDown;	
    }
     
    Card.prototype = {
     
        explo: function(){
    alert(this.faceDown);	
    }
    };
    je bind de cette facon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for(var k=0; k < 24; k++){
    				Game.card.push(new Card("true"));
    				$($(document.images[k])).click(Game.card[k].explo);
    			}
    lorsque que je click sur mes cartes à l'ecran faceDown est undefined, je ne connais pas jquery asser mais j'imagines que mon probleme vient du fait que je melange du DOM et jquery un peu trop... je veux bind l'evenement click sur tout mes card qui se trouve dans un Array... ce qui est bizzare cest que lorsque je click l'alert me dit undefined mais si j'apelle manuellement:

    Game.card[0].explo(); j'obtient le "true"...



    quelqu'un à un idée ?

  6. #6
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 130
    Points
    9 130
    Par défaut
    encore une fois js est un langage à objet.
    les objet ont donc des membres et des méthodes.
    lorsque tu fais $($(document.images[k])).click(Game.card[k].explo) tu ne fais pas tout a fait ce que tu crois ou que tu veux faire.

    déjà Jquery te masque certaines choses et ça rand la comprehention plus obscure. en javascript tout cour ton bout de code serait quelque chose comme document.getElementById(document.images[k]).click=Game.card[k].explo; et tu vois ici que tu fais une affectation.
    tu affecte le membre clic de l'image.
    pour être précis c'est comme si tu définissait la méthode click de l'image en lui donnant le code de la méthode explo. (si tu as fais du c++ tu affect à click un pointeur sur la fonction explo)

    tu vois clairement que l'immage n'a aucune référence à ton objet Game.card[k]du coup lorsque tu clique le code qui s'execute est alert(this.faceDown); mais c'est le membre de l'objet image this est donc une référence à l'image.
    alert(document.getElementById(document.images[k]).faceDown);
    Jquery est une belle lib mais pour débuter je déconseille de l'utiliser. elle trompe trop le développeur sur la vrais nature de ce qu'il fait

    pour ce qui est du binding deux solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(var k=0; k < 24; k++){
      Game.card.push(new Card("true"));
      document.getElementById(document.images[k]).click=function () {Game.card[k].explo();}
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(var k=0; k < 24; k++){
      document.getElementById(document.images[k]).card = new Card("true");
      document.getElementById(document.images[k]).click=function (){this.card.explo();}
    }
    dans la première tu as un tableau de Game card et tu appelle la methode explo d'un objet du tableau
    dans la deuxième tu n'as plus de tableau mais chaque image est associé à sa propre game card

    pour moi la deuxième est celle qui est le plus proche de l'esprit du langage
    la plus "objet". elle utilise les capacités des objets à s'enrichir de membres ou de méthodes. elle évite d'avoir des varaibles globales (comme ici l'objet Game) qui traine pour ceci ou cela. Mais les deux solution ont leurs avantages.

    on peut mixer les deux si ont veut conserver le tableau et tout de même associer l'image et la carte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for(var k=0; k < 24; k++){
      Game.card.push(new Card("true"));
      document.getElementById(document.images[k]).card = Game.card[k].explo();
      document.getElementById(document.images[k]).click=function (){this.card.explo();}
    }
    A+JYT

  7. #7
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Pas grand chose à rajouter, si ce n'est que document.getElementById(document.images[k]) ne fonctionnera pas puisque document.images[k] n'est pas un id mais un objet de type HTMLElement

    A part ça, d'accord aussi sur le fait d'éviter jQuery pour débuter avec JavaScript (d'autant que l'utilisation que tu sembles en faire ne justifie à priori pas son utilisation), mais pour info
    te sers à transformer l'objet images[k] en objet jQuery, donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $($(document.images[k]))
    ne sert strictement à rien : le $() le plus englobant étant inutile !

  8. #8
    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
    Je ne pense pas que jQuery soit vraiment le problème : avec ou sans il faut quand même comprendre les mécanismes de scope et les nombreux sens du mot-clé this.

    Esquiver le problème en passant des fonctions intermédiaires et en passant des variables à un scope plus englobant n'est pas une vraie solution, j'ai déjà vu les dégâts que cela pouvait occasionner chez les débutants : centaines de variables globales, conflits, effets de bord etc...

    Et je déconseille l'approche de sekaijin qui étend les propriétés d'un élément DOM. Les éléments DOM ont des tas et des tas de propriétés et méthodes, dont la plupart des gens ne connaissent pas la moitié. Le risque de conflit par erreur est trop fort.

    Il vaut mieux augmenter l'abstraction sur l'objet (objet.elm = monDOMElement) et déclarer une variable en closure ou utiliser un proxy (équivalent de call/apply en jQuery):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for(var k=0; k < 24; k++){
       var card = new Card();
       card.elm = $(".image-"+k);
       Game.cards.push(card);
       card.elm.click( $.proxy( card.explo, card ) );
    }

  9. #9
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 130
    Points
    9 130
    Par défaut
    Je suis d'accord avec toi sur la possibilité d'en richir l'objet Card mais dans ce cas je ferais plutôt quelque chose comme
    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 Card(faceDown, elem){
      this.faceDown = faceDown;	
      this.setElem(elem);
    }
     
    Card.prototype = {
      faceDown :null,
      elem:null,
      explo: function(){
        alert(this.faceDown);	
      },
      setElem: function(elem) {
        this.elm = elem;
        var scope = this;
        this.elm.click( $.proxy( this.explo, sope) );
      }
    };
    et ensuite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(var k=0; k < 24; k++){
       Game.cards.push(new Card("true", $(".image-"+k)));
    }
    @Bovino
    c'est pour ça que j'ai dit
    ton bout de code serait quelque chose comme
    A+JYT

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 162
    Points : 209
    Points
    209
    Par défaut
    Salut,

    J'ai cru comprendre que le dernier bout de code a été fait à "la va-vite", mais est-ce judicieux de mettre dans le prototype de Card une référence vers l'objet dom (elem) ? Cela signifierait que chaque objet Card possède le même objet elem ?

    Mis à part ça, je rejoins SylvainPV sur l'approche de ne pas étendre les propriétés de l'objet DOM, mais de pointer vers l'élément DOM. Le tout (sauf la référence vers l'objet DOM en l'occurence) encapsulé dans le prototype pour éviter une trop grande empreinte mémoire (duplication inutile des fonctions getter, et setter par exemple), et je pense que l'on obtient une implémentation plutôt correcte.

    A+

  11. #11
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    mais est-ce judicieux de mettre dans le prototype de Card une référence vers l'objet dom (elem) ? Cela signifierait que chaque objet Card possède le même objet elem ?
    Non.
    Card est un constructeur, chaque instance de ce constructeur devra passer en paramètre l'objet DOM auquel il est rattaché.

  12. #12
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 130
    Points
    9 130
    Par défaut
    mon propos dans ce bout de code fait à la va vite est de dire que si on fait porter à card une référence à l'élément auquel il est associé autant le faire dans le prototype et le constructeur que je le mettre dnas un code à part

    je n'ai pas regardé précisément s'il était correct
    A+JYT

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 162
    Points : 209
    Points
    209
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Non.
    Card est un constructeur, chaque instance de ce constructeur devra passer en paramètre l'objet DOM auquel il est rattaché.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Card.prototype = {
      faceDown :null,
      elem:null,
      explo: function(){
        alert(this.faceDown);	
      },
      setElem: function(elem) {
        this.elm = elem;
        var scope = this;
        this.elm.click( $.proxy( this.explo, sope) );
      }
    };
    La déclaration "elem" dans le prototype est inutile dans ce cas, et peut même porter à confusion, non ?

  14. #14
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Ca permet de préciser que l'objet Card possède une propriété elem, qui sera définie par le constructeur. Et comme elem est un paramètre du constructeur, chaque instance possédera une propriété elem distincte.

    Ensuite, porter à confusion, pas vraiment, le fonctionnement est assez clair à la lecture du code.

Discussions similaires

  1. initialisation de variable d'instance
    Par GO dans le forum C++
    Réponses: 7
    Dernier message: 04/11/2006, 12h51
  2. redéfinition de variable d'instance
    Par swinger45 dans le forum Langage
    Réponses: 8
    Dernier message: 27/09/2006, 19h34
  3. Collection et variable non instancié
    Par david06600 dans le forum Langage
    Réponses: 1
    Dernier message: 17/08/2006, 15h23
  4. Variable d'instance et classe anonyme
    Par zoullou dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 21/05/2006, 13h30
  5. [POO] Retrouver une variable d'instance de classe
    Par stailer dans le forum Langage
    Réponses: 1
    Dernier message: 18/02/2006, 11h56

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