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 :

Incompréhension des array dans un objet


Sujet :

JavaScript

  1. #1
    Membre régulier
    Inscrit en
    Avril 2007
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 115
    Points : 75
    Points
    75
    Par défaut Incompréhension des array dans un objet
    Bonjour,
    j'essaie en ce moment de faire quelque chose d'un minimum construit en javascript et je me bute à un souci que j'ai un peu de mal à comprendre. La question a peut-être été déjà posée, mais je n'ai rien trouvé de mon côté.

    Je créé des objets par cette méthode :
    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
    Object= (function () {
        var truc= function(name) { // Constructor
            if (name) {
                this.setTruc(name);
            }
        };
        truc.prototype =  {
            table : [],
            addTable : function (name, url, x, y) {
                this.table [String(name)]
            }
            getTable : function (name, url, x, y) {
                this.table [String(name)]
            }
        };
        return {
            truc: truc
        };
    })();
    Que je peux par la suite instancier ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var personnage = new Object.truc();
    personnage.addTable ('test');
    var personnage2 = new Object.truc();
    personnage2.addTable ('2');
    personnage2.addTable ('test3');
    personnage2.getTable ();
    Peu importe comment j'instancie les objets, ils utilisent tous le même tableau derrière ... C'est à dire que quand je fais un getTable par exemple, il me retourne tout ce que j'ai mis, que ce soit dans personnage ou dans personnage2, aucune différence est faite.

    Est-ce le javascript qui est comme ça ou j'utilise mal les notions objets de ce langage ? C'est assez surprenant, vu que je viens de d'autres langages objets. Y a t'il des solutions pour arriver à faire ce que je voudrais ? C'est à dire séparer une instance d'une autre ?

    Merci !

  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
    Effectivement c'est une erreur de compréhension du fonctionnement des prototypes.

    Tous les objets héritent et partagent les propriétés de leurs prototypes. Si tu déclares la variable table dans le prototype, toutes tes instances vont partager cette même variable.

    Sinon, ton code écrase le constructeur Object... c'est-à-dire le constructeur de tous les objets en JavaScript !!! A ne surtout pas faire
    One Web to rule them all

  3. #3
    Membre régulier
    Inscrit en
    Avril 2007
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 115
    Points : 75
    Points
    75
    Par défaut
    Je vois ! Cela dit mon problème reste entier. Je voudrais faire de l'objet, avec des namespace et que les objets instanciés soient bien distinctes les uns des autres. Avez-vous une idée de comment ça peut se faire ? Je pense que j'ai du passer à côté de quelque chose !

  4. #4
    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
    Il y a plusieurs façons de faire de l'objet en JavaScript. Le langage se veut multi-paradigme, pour le meilleur et pour le pire. La plupart des tutos que tu trouveras ici sont basés sur les constructeurs, et je pense que tu as voulu reprendre le même paradigme. Je ne comprends pas ton exemple, mais il pourrait sans doute être écrit de cette manière :

    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
    (function () { 
        var Truc= function(name) { // Constructor
            this.table = [];
            if (name) {
                this.name = name;
            }
        };
     
        Truc.prototype =  {
            addTable : function (key, value) {
                this.table[String(key)] = value;
            }
     
            getTable : function (key) {
                return this.table[String(key)];
            }
        };
     
     var personnage = new Truc();
      personnage.addTable('test');
     
      var personnage2 = new Truc();
      personnage2.addTable('2', "valeur");
      personnage2.addTable('test3', "test");
      personnage2.getTable('2');
     
    });
    Ceci dit, ce n'est pas la seule manière de faire. Personnellement je préfère ne pas utiliser l'opérateur new : http://www.developpez.net/forums/d14...aise-pratique/
    One Web to rule them all

  5. #5
    Membre régulier
    Inscrit en
    Avril 2007
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 115
    Points : 75
    Points
    75
    Par défaut
    Merci pour ta réponse. Alors plus précisément ma classe ressemble à ça :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
     
    Swoosh = (function () {
        /**
         * Methods
         */
     
        // Canvas
        var canvas = function(name) { // Prototype
            if (name) {
                this.setCanvas(name);
            }
        };
     
        canvas.prototype = {
            setCanvas : function (name) {
                    Swoosh.id = document.getElementById(name);
                    Swoosh.context = Swoosh.id.getContext("2d");
            },
        };
     
        // Images
        var image = function () {
            // prototype 
            this.sprites = [];
        };
     
        image.prototype =  {
            /**
             * Sprites will contain an array of images and its properties
             * @type Array
             */
            sprites : [],
     
            imageInstance : [],
     
            imagesLoaded : false,
     
            addSprite : function (name, url, x, y) {
                this.imagesLoaded = false;
     
                image = new Image();
                image.src = url;
                image.onload = function() { 
                    this.imagesLoaded = true;
                };
     
                var properties = {url: url, image: image, x: x, y: y};
                this.imageInstance[name] = properties;
                this.sprites = this.imageInstance;
     
                return this.sprites[String(name)];
            } ,
     
            /**
             * Adds a sheet with multiple images that can be devided.
             * @param Array division : an array of 4 axis to devide each images and name them ?
             */
            addSpriteSheet : function (name, url, x, y, division) {
     
            },
     
            getSprites : function () {
                return this.sprites;
            },
     
            getSprite : function (name) {
                return this.sprites[String(name)];
            },
     
            /**
             * Showing image functions
             */
     
            // Shows all images 
            show : function (x, y) {
                for (var key in data = this.sprites) {
                    var sprite = data[key];
     
                    Swoosh.context.drawImage(sprite.image, sprite.x, sprite.y);
                }
            },
     
            // shows image and associated images only
            showPart: function (name, x, y) {
                x = x || 640;
                y = y || 480;
     
                var sprite = this.getSprite(String(name));
                Swoosh.context.drawImage(sprite.image, sprite.x, sprite.y); 
            },
     
            /**
             * Animation functions
             */
            // Moves all the images
            moveTo : function (x, y) {
                this.refresh();
                for (var key in data = this.sprites) {
                    this.movePartTo(key, x, y);
                }
            },
     
            // Moves the sprite and associated sprites only
            movePartTo : function (name, x, y) {
                Swoosh.context.drawImage(sprite.image, sprite.x, sprite.y);
            },
     
        }
     
     
        return {
            canvas : canvas,
            image : image
        };
     
     
    })();
    Voilà, globalement j'instancie une objet image pour gérer une plusieurs images d'un array (ou d'un objet) en même temps. Et ça fonctionne très bien jusqu'à ce que je me rende compte que le tableau est global à tous les objets instanciés.

    Alors ton code fonctionne très bien, mais si j'instancie le tableau dans le constructeur avec cette classe, ça ne change absolument rien !

  6. #6
    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
    Dans le code ci-dessus, le tableau sprites est toujours dans le prototype
    One Web to rule them all

  7. #7
    Membre régulier
    Inscrit en
    Avril 2007
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 115
    Points : 75
    Points
    75
    Par défaut
    Tu veux dire que l'utilisation du tableau, pour ce que je veux faire, ne doit pas être dans un prototype ?

    Si je mets cette ligne en commentaire : sprites : [], ça ne change rien. C'est donc l'utilisation du tableau ?

  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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    this.imageInstance[name] = properties;
    this.sprites = this.imageInstance;
    Je ne comprends pas ce code. imageInstance est aussi dans le prototype, donc tu fais pointer sprites sur une référence au prototype. C'est quoi ces deux tableaux, à quoi ça rime ?
    One Web to rule them all

  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 127
    Points
    9 127
    Par défaut
    ça n'a rien à voir avec les tableaux.

    en java, PHP ou en C++
    si tu créés une variable d'instance chaque instance possède un exemplaire de la variable.

    si tu créés une variable de classe toutes les instances se partagent la même variable.

    Il en va de même avec les prototype
    Si tu crée une variable d'instance chaque instance possède un exemplaire de la variable.
    si tu créés une variable dans le prototype toutes les instances se partagent la même variable.


    Ceci est vrai pour tous les langages à objets qui supportent les notions de variable d'instance et de classe/prototype

    Ceci est vrai quelque soit la nature de la variable.


    C'est donc à toi développeur de savoir ce que tu veux faire.


    le plus simple pour commencer la POO et ce quelque soit le langage est de se concentrer sur les variables d'instances. (les variables de classe/prototype ne sont pas si primordiales certains font même l'impasse dessus)

    du coup pour créér des objet en JS il suffit de faire des constructeurs
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    // Canvas
        var canvas = function(name) { // constructeur
            this.setCanvas : function (name) {
                    Swoosh.id = document.getElementById(name);
                    Swoosh.context = Swoosh.id.getContext("2d");
            };
            if (name) {
                this.setCanvas(name);
            }
        };
     
     
     
    // Images
        var image = function () {
            // constructeur
            this.sprites = [];
            /**
             * Sprites will contain an array of images and its properties
             * @type Array
             */
            this.sprites : [];
     
            this.imageInstance : [];
     
            this.imagesLoaded : false;
     
            this.addSprite : function (name, url, x, y) {
                this.imagesLoaded = false;
     
                image = new Image();
                image.src = url;
                image.onload = function() { 
                    this.imagesLoaded = true;
                };
     
                var properties = {url: url, image: image, x: x, y: y};
                this.imageInstance[name] = properties;
                this.sprites = this.imageInstance;
     
                return this.sprites[String(name)];
            };
     
            /**
             * Adds a sheet with multiple images that can be devided.
             * @param Array division : an array of 4 axis to devide each images and name them ?
             */
            this.addSpriteSheet : function (name, url, x, y, division) {
     
            };
     
            this.getSprites : function () {
                return this.sprites;
            };
     
            this.getSprite : function (name) {
                return this.sprites[String(name)];
            };
     
        };
    je n'ai pas regardé ton code ce que je te présente c'est juste le principe.
    Dans cette façon de faire il n'est question que de membres d'instances donc rien de partagé.

    A+JYT

  10. #10
    Membre régulier
    Inscrit en
    Avril 2007
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 115
    Points : 75
    Points
    75
    Par défaut
    SylvainPV : je construis un tableau(avec une image et des propriétés) ayant un nom comme clé, que je met dans un tableau plus global contenant plusieurs tableaux. Je dois avoir du mal à comprendre l'utilité des prototypes parce que pour moi ça a l'air assez clair ! Merci pour ton lien sur l'opérateur new !

    sekaijin : effectivement c'est exactement ce que je voulais faire ! Mais je me rends compte que ma connaissance de ce langage est encore assez sommaire ! Je n'ai trouvé aucune bonne documentation sur les objets en javascript, pas faute d'avoir cherché !
    Hum alors, par rapport aux variables d'instances et de classes, effectivement, ça m'a l'air plus logique dit comme ça ! Mais comme aucun mot clé ne spécifie la variable, j'ai cru que j'utilisais des variables d'instances à chaque fois, c'est un peu perturbant !

    Merci à vous deux !

  11. #11
    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
    Si imageInstances est un tableau contenant toutes les instances d'Image, alors ça n'a rien à faire dans le prototype. Ça reviendrait à ce que chaque objet contienne une référence à tous les autres objets de son type, y compris lui-même.

    Pour le tableau sprites, s'il est propre à chaque instance, pourquoi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.sprites=this.imageInstance;

    ce qui le réassigne au tableau contenant toutes les instances ?

    Et non il n'y a pas de préfixe particulier pour les variables dans le prototype.... tout simplement parce que n'importe quel objet en JS peut être le prototype d'un autre !
    One Web to rule them all

  12. #12
    Membre régulier
    Inscrit en
    Avril 2007
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 115
    Points : 75
    Points
    75
    Par défaut
    Donc ça vient bien d'une incompréhension des prototypes. Si je comprends bien un prototype permet donc de faire des methodes propres à la classe et non à l'instance ?

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

Discussions similaires

  1. [Tableaux] Insérer des arrays dans des arrays
    Par DJ Caësar 9114 dans le forum Langage
    Réponses: 2
    Dernier message: 01/06/2009, 13h03
  2. Liste des voxels dans un objet 3D
    Par PhilB21 dans le forum Moteurs 3D
    Réponses: 0
    Dernier message: 29/05/2009, 10h06
  3. modifier des valeurs dans l'objet Request?
    Par airod dans le forum Zope
    Réponses: 2
    Dernier message: 27/05/2008, 15h36
  4. Ajouter des données dans un objet Listbox
    Par nuans dans le forum Interfaces Graphiques
    Réponses: 11
    Dernier message: 23/05/2007, 11h49
  5. Ecrire des valeurs dans un objet OLE Excel
    Par NewbiePower dans le forum Access
    Réponses: 4
    Dernier message: 08/02/2007, 08h59

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