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 :

Arguments différents pour un objet instancié


Sujet :

JavaScript

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut Arguments différents pour un objet instancié
    Bonjour,

    Ca fait un moment que je tourne autour de ce problème et n'ayant pas trouvé de solution ou de contournement je me demande si c'est possible.

    L'idée c'est d'instancier un objet avec new et des arguments qui serviront à l'initialisation de l'objet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    obj = new debug(x,y,z);
    et d'obtenir un objet "obj" qui attendra d'autres arguments
    par exemple:

    il s'agit de creer une fenetre de log à laquelle l'objet sera associé, en gardant une syntaxe la plus simple possible.


    Je sais que le polymorphisme paramétrique n'est pas possible en javascript puisque non typé mais j'espérais au moins pouvoir redéfinir l'objet pendant le traitement mais je n'y arrive pas.

    Est-ce que ca parle à quelqu'un ? tant que je ne serais pas convaincu que c'est impossible je tournerais en rond... et pour l'instant c'est le cas.

    Merci

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 162
    Par défaut
    Bonjour,

    Je ne sais pas si j'ai bien compris le problème, mais ça ne me semble pas impossible à faire, peut-être peux-tu t'inspirer de ce bout de code :
    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
    <html>
    	<head>
    		<script type="text/javascript">
    			var LoggerFactory = function(){
     
    				if ( LoggerFactory.caller != LoggerFactory.getInstance ) {
    					throw new Error("This object cannot be instanciated");
    				} 
     
    				LoggerFactory.prototype.buildLogger = function(params){
    					var Logger = function(width, height, x, y){
    						this.loggerDiv = document.createElement("div");
    						this.loggerDiv.style.backgroundColor = "red";
    						this.loggerDiv.style.position = "absolute";
    						this.loggerDiv.style.top = y+"px";
    						this.loggerDiv.style.left = x+"px";
    						this.loggerDiv.style.width = width+"px";
    						this.loggerDiv.style.height = height+"px";
     
    						document.body.appendChild(this.loggerDiv);
    					}
     
    					Logger.prototype.log = function(chaine) {
    						this.loggerDiv.innerHTML = "<div>"+chaine+"</div>"+this.loggerDiv.innerHTML;
    					}
     
    					return new Logger(params.width, params.height, params.x, params.y);
    				}
     
    			};
     
    			/* fonction anonyme "auto-exécutée" pour le singleton */
    			(function(){
     
    				var instance = null;
     
    				LoggerFactory.getInstance = function() {
    					if (instance == null){
    						instance = new LoggerFactory();
    					}
    					return instance;
    				}
    			})();
     
    			var debug1 = null;
    			var debug2 = null;
     
    			window.onload = function(){
     
    				var loggerFactory = LoggerFactory.getInstance();
     
    				debug1 = loggerFactory.buildLogger({"width":400,"height":300,"x":50,"y":50});
    				debug2 = loggerFactory.buildLogger({"width":200,"height":200,"x":400,"y":300});
     
    				debug1.log("test1");
    				debug2.log("test2");
    			}
    		</script>
    	</head>
    	<body>
    	</body>
    </html>
    J'utilise un singleton pour construire les objets, mais rien ne t'empêche d'avoir plusieurs instances qui construisent tes objets, cela dépend de ton contexte...

    Tu peux ainsi construire des objets avec des paramètres différents.

    J'espère que cela répond à tes interrogations sur la faisabilité de ton problème...

    A+

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut
    Merci pour ta réponse, qui m'apporte quelques pistes intéressantes sur la façon d'utiliser "caller", les instances, "this" et tutiquanti. Je me fais encore des sacs de noeuds quand j'essaie d'appréhender JS, peut-être qu'avec le temps ca me sera plus naturel.

    Tu appelle une méthode de l'objet debug, dans ce cas on peut creer autant de méthodes que de contextes.

    Mon interrogation c'est plutôt "comment instancier un objet en changeant sa liste d'arguments dans le constructeur"... en fait ca me parait pas très logique, mais comme il me reste des doutes...

    De manière à avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    dump1 = new debug(10,10,80,25); // x,y,colones, lignes
    dump1 ("test"); // affiche test dans la fenêtre de debug
    sans appeler une méthode de l'objet debug donc.
    Il y a plusieurs façons d'écrire tout ça mais en le faisant je me suis posé ces questions pas super logiques et depuis ca m'obsède un peu.

    Donc, sans faire de test sur les arguments non plus.

    Au final je ne pense pas que ce soit possible, il faudrait accéder à l'instance avant qu'elle soit construite voire la redéfinir dynamiquement ou la reconstruire. Après il y a peut-être des solutions bas niveau... mais j'ai encore trop de sacs de noeuds pour continuer à explorer tout seul

    Est-ce que ma question n'est pas trop flou?

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 162
    Par défaut
    En fait, il y aurait une solution mais qui n'est pas propre du tout :
    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
    <html>
       <head>
          <script type="text/javascript">
             var toto = function(titre){
                return function(chaine){
                   alert(titre+" chaine = "+chaine);
                }
             }
     
             var test = new toto("test1");
             test("essai");
             var test2 = new toto("test2");
             test2("essai2");
          </script>
       </head>
       <body>
       </body>
    </html>
    Tu construis une fonction dont tu retournes la référence, après selon le paramètre initial, tu peux retourner des fonctions dont la signature est différente si je saisis bien ton besoin... (bien qu'il est possible d'utiliser la variable "arguments" pour gérer le nombre de paramètres d'une méthode).

    Je n'ai pas vraiment saisi l'intérêt de la chose, mais c'est possible.

    A+

  5. #5
    Membre Expert Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Par défaut
    Babeuh a déjà répondu de façon assez complète :

    1) le mieux est de faire un objet avec méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function console(params){
        this.interface = /* creation de l'interface */;
    }
    console.prototype.log = function(text){
        this.interface.write(text);
    };
     
    var console1 = new console(x,y);
    var console2 = new console(z,w);
    console1.log('text');
    ou si tu veux vraiment te passer de méthodes d'un objet

    2) une fonction renvoyant une fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function console(params){
         var interface = /* creation de l'interface */;
         function logger(text){
              interface.write(text);
         }
         return logger;
    }
     
    var console1 = new console(x,y);
    var console2 = new console(z,w);
    console1('text');

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut
    Merci à tous pour votre aide, j'avance sur des subtilités en travaillant sur vos exemples.

    J'ai donc vite fais une fonction sans méthode, c'est vrai ce n'est pas très propre:

    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
        function debug(x,y,l,c,b){
     
            "use strict";
     
            this.x=(x||10)+'px';
            this.y=(y||10)+'px';
            this.l=l||10;
            this.c=c||10;
            this.b=b||'grey';
     
     
            var tdiv = document.createElement("DIV");
                tdiv.style.position='absolute';
                tdiv.style.top=this.x;
                tdiv.style.left=this.y;
                tdiv.style.backgroundColor=this.b;
                tdiv.style.opacity=.75;
            var tform=document.createElement("FORM");
            var ttext=document.createElement("TEXTAREA");
                ttext.style.backgroundColor="transparent";
                ttext.cols=this.c;
                ttext.rows=this.l;
                tform.appendChild(ttext);
                tdiv.appendChild(tform);
     
                document.body.appendChild(tdiv);
     
            return function(txt){
                ttext.value=txt;
            }
        }
     
        test=new debug();
        test1=new debug(10,200,25,50,"red");
        test1("Dans test1");
        test("Dans test");
    La difficulté dans ce cas c'est de comprendre comment l'objet reste liée aux variables locales de l'instance, puisque l'instance contient seulement une fonction en apparence... et de plus l'utilisation de "this" n'est plus possible.

    Je pense que je ferais la chose avec des méthodes et/ou avec filtrage des arguments mais l'intérêt est pour moi d'explorer les diverses possibilités de traiter un problème en JS, en l’occurrence bosser un peu la façon de passer des arguments et d'accéder aux variables. C'est vrai qu'entre taper debug(txt) et debug.log(txt) il n'y a pas grande différence mais peut-être que dans d'autres cas ça pourrait me servir. Au final j'ai besoin de comprendre ce qui est le plus "correct" et qui peut être le plus "joli", et aussi comment ça "tourne".

  7. #7
    Membre Expert Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Par défaut
    en fait mon 2ème exemple (que tu utilises dans ton dernier message) utilise la porté des variable (encapsulation, etc...) :

    les variables d'une fonction pouvant avoir le même nom, elle dépend de l'endroit où la fonction est définie :

    exemple :

    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
    var myvar; // global
    function creation(){
        myvar; // utilisation du myvar global car par le mot clé "var" devant
        var interne  = function (){
            myvar; // utilise le myvar global 
        };
    }
     
    var myvar; // global
    function creation(){
        var myvar; // myvar différent du global, nouvelle variable
        var interne = function(){
            myvar; // utilise le myvar local de creation(3 lignes plus haut), un nouveau myvar sera défini pour chaque appel de creation
        };
    }
     
    var myvar; // global
    var _interne = function(){
        myvar; // utilise le global même si la fonction est appelée ailleurs (dans une autre fonction) le contexte reste celui de la déclaration (ici).
    };
    function creation(){
        myvar;
        var interne = _interne; // interne pointera vers la fonction _interne définie a l'exterieur de ce contexte, il n'aura donc pas accès aux données locales.
    }
    enfin un contexte n'est défini que par les fonctions (en gros) donc par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var myvar; 
    if(cond){
      var myvar; // même contexte que 2 lignes plus haut, le var est donc inutile et le myvar 2 lignes plus haut sera affecté... une seule et unique même variable 
    }
    enfin, une dernière chose

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var myvar; // global
    function creation(){ 
        var myvar; // définition local
        myvar; // il existe un myvar local ... donc c'est celui là qui est utilisé
    }
    équivaudra à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var myvar; // global
    function creation(myvar){ // les arguments définissent également une portée locale
        myvar; // utilise donc le myvar local (même s'il vaut "undefined" car aucun  arguments n'a été passé lors de l'appel)
    }

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Juillet 2011
    Messages : 4
    Par défaut
    Je reviens après avoir essayé pleins de façons de le faire. Ca m'a permis de mieux comprendre la structure de JS mais je l'ai quand même fais avec un objet qui initialise des éléments et renvoi une fonction à l'instance.
    Merci encore pour vos exemples.

    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
    function debug2(args){
     
     
        if (!slot) {
            var slot = doSlot();  // Div et textarea
            fitSlot(slot,args);     // position couleur etc
            slot.ttext.onclick = function(){light(slot)};   // fonction pour le focus
        }
     
        return function(args){
            if (args.x||args.y||args.l||args.c||args.bg||args.op||args.z)    fitSlot(slot,args);  // changer position couleur etc
            else
            (args==="" && slot) ? slot.ttext.value="" : slot.ttext.value+=args; // sortie d'un texte
        }
    }
     
    function light(slot){
             slot.backColor=slot.style.backgroundColor;
             slot.style.backgroundColor='blue';
             if(document.lastSlot) {document.lastSlot.style.backgroundColor=document.lastSlot.backColor;}   
             document.lastSlot=slot;
    }
    Ca fonctionne même si j'ai encore du boulot pour jouer avec JS.

    J'ai tellement essayé de choses pour la fonction light, mais j'ai vraiment du mal vu que ce n'est pas simple d'avoir des variables statiques et d'éviter les globales, et une closure dans ce contexte ca m’échappe apparemment. Il s'agit pour l'exemple de changer la couleur de la sortie cliquée puis de la restituer si une autre sortie est cliquée.

    Comment feriez vous pour ne pas stocker la réference (si ca en est une) dans document et éviter une globale ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/05/2011, 15h27
  2. Réponses: 4
    Dernier message: 10/12/2009, 19h25
  3. [EJB Stateful] Instances différentes pour 2 instances remote d'un même client ?
    Par Askerat dans le forum Java EE
    Réponses: 2
    Dernier message: 02/05/2009, 21h28
  4. otpion de jvm différentes pour chaque instance Jboss
    Par germain35 dans le forum Wildfly/JBoss
    Réponses: 1
    Dernier message: 26/01/2009, 10h40
  5. Réponses: 15
    Dernier message: 19/06/2006, 19h25

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