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 :

Javascript POO window[fnstring](param)


Sujet :

JavaScript

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Points : 121
    Points
    121
    Par défaut Javascript POO window[fnstring](param)
    Bonjour,

    J'essaye d'appliquer le paradigme POO à mon code javascript. Mais je bloque sur un message d'erreur

    Uncaught TypeError: window[fnstring] is not a function

    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
    class Test {
    
     // FONCTION QUI CONVERTIT UN STRING EN FONCTION
     stringToFunction(rule, idField) { 
      
      var fnstring = rule;  //string
      var param = idField; /: objet
    
      var fn = window[fnstring](param);  //  this ? lorsque je sors tout mon code de la classe, cela fonctionne. Dans la class = window[fnstring] is not a function ?
        
      if (typeof fn === "function") {
       return fn();
      } else {
       console.log(typeof(fn)); 
      }
     } 
    
     // FONCTION QUI BOUCLES SUR LES REGLES 
     controls (idField, action, rules) { 
     
      var that = this; 
    
      idField.addEventListener(action, function() {
    
       for (var i = 0 ; i <rules.length; i++) {
    
        let rule = rules[i];
        let error; 
    
        that.stringToFunction(rule, idField);  
    
       ...
    
       }
      });
     }
    
    } // FIN CLASS
    
    nom = document.getElementById('nom'); 
    
    var test1 = new Test(); 
    test1.controls(nom, 'focusout', ['test1', 'test2'];
    Merci pour vos explications et vos conseils accessibles pour un autodidacte....

  2. #2
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Bonjour,
    Apparemment l'instance de la classe et la première fonction ont le même nom, test1, ce qui est problématique si elles sont définies dans le même contexte (la seconde définition écrasera la première).
    Il faudrait renommer l'un des deux.
    A tester : function f1(){}, puis test1.controls(nom, 'focusout', ['f1', 'test2']);.

    Par ailleurs :

    - Il y a deux erreurs de syntaxe dans ce script (commentaire /: objet, et appel de fonction où il manque la parenthèse fermante), mais j'imagine que ce sont des erreurs de retranscription.

    - Une amélioration de conception serait de passer directement les fonctions plutôt que leur nom :
    test1.controls(nom, 'focusout', [f1,test2]);
    La classe n'a en effet pas besoin de savoir où se trouve la fonction.

    - Concernant l'utilisation de let et var : la tendance sera plutôt de n'utiliser que l'un des deux : soit que des let (ou const, selon les cas), soit que des var, sachant que les règles de portée sont différentes, mais qu'on peut bien sûr arriver au même résultat final.

    - Les noms des variables sont plutôt mal choisis, exemple :
    idField conviendrait pour une chaîne de caractère, mais pas pour un élément html.
    Ce serait plus clair comme ceci :
    * Un champ html : let field;.
    * L'identifiant de ce champ : let idField;.
    On peut aussi mettre le type dans le nom, voici des possibilités :
    * Une chaîne contenant un nom : st_nom, sNom.
    * Un nombre spécifiant un numéro : nb_numero, nb_no, nNumero, nNo...
    Si on ne spécifie pas le type, il faut au minimum veiller à ce que le nom choisi permette de deviner intuitivement son type, ou du moins ne soit pas déroutant comme dans le cas présent.

    Etc.

  3. #3
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Points : 121
    Points
    121
    Par défaut
    Merci pour votre retour mais je n'y arrive pas avec une class

    je vous laisse un exemple simplifié

    index.html
    Code HTML : 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
    <!DOCTYPE html>
    <html>
    <head>
     <title> CLASS JS</title>
     <meta charset="utf-8">
    </head>
    <body>
     
     <form method="post" action="traitement.php" id="formId">
     
      <input type="text" name="nom" id="nom" placeholder="NOM"></input>
      <input type="submit" name="envoyer" value="ENVOYER">
     </form>
     
     <script src="controlForm.js"></script>
     <script src="mainForm.js"></script>
     
    </body>
    </html>

    mainForm.js
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var nom = document.getElementById('nom'); 
     
    control1 = new Control(); 
    console.log(control1); 
     
    //nom = html Element
    // focusout = action
    // isRequired, isAlpha = nom des fonctions à appliquer au champ 
    control1.verif(nom, 'focusout', ['isRequired', 'isAlpha']);
    controlForm.js
    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
    class Control {
    
     // FONCTION QUI CONVERTIT UN STRING EN FONCTION
     stringToFunction(rule, field) { 
      var fnstring = rule; // type string
      var param = field;  // type object
    
      // controlForm.js:10 Uncaught TypeError: window[fnstring] is not a function
      var fn = window[fnstring](param); //Cela marche hors class !!! POURQUOI  PAS DANS UNE CLASS ??
    
      if (typeof fn === "function") {
       return fn();
      } else {
       console.log(typeof(fn)); 
      }
     } 
    
    // FONCTION QUI TESTE LES REGLES A PASSER AU CHAMP
     verif (field, action, rules) { // on passe en paramètre les règles que l'on veut appliquer à un champs
      var that = this;
      //console.log(field); 
      //console.log(action); 
      //console.log(rules); 
    
      field.addEventListener(action, function() {
       for (var i = 0 ; i < rules.length; i++) {
    
        // appel de la fonction qui transforme un string en fonction 
        that.stringToFunction(rules[i], field);  
        console.log(error); 
       }
      });
     }
    
    // FONCTION QUI TESTE SI LE CHAMP EST VIDE
     isRequired(field) {
      if (field.value == "") {
       return error = true; 
      } else {
       return error = false; 
      }
     } 
    
    // FONCTION QUI TEST SI LE CHAMP EST ALPHA....
     isAlpha(stfield) {
      var regex_text = new RegExp(/^[A-Z._'-\s]{2,20}$/); 
      if(field.value !== "") {
       if(field.value.length < 2 || field.value.length > 20) {
        return error = true; 
       } else if (!regex_text.test(field.value)) {
        return error = true; 
       } else {
        return error = false; 
       }
      } else {
       return error = false; 
      } 
     }
    
    } // FIN CLASS
    pourquoi le message d'erreur window[fnstring](param) apparaît dans une class et fonctionne très bien hors Class ???

    Merci pour vos retours et si vous aviez une solution à mon problème...j'en peux plus

  4. #4
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Si les fonctions sont des méthodes de la classe, c'est normal qu'elles ne soient pas définies sur window.
    Voici un exemple où on appelle une fonction définie sur window et une fonction de la classe à partir des noms des fonctions :
    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
    <script>
    function fa() {
    		console.log("fa");
    }
     
    class Test {
    	constructor(nomFonctionDefinieSurWindow,nomFonctionDeLaClasse) {
    		window[nomFonctionDefinieSurWindow]();
    		this[nomFonctionDeLaClasse]();
    	}
    	fb() {
    		console.log("fb");
    	}
    }
     
    new Test("fa","fb");
    </script>
    La solution est donc d'écrire : var fn = this[fnstring](param);
    Suite à cette correction, de ce que j'ai vu, d'autres problèmes vont survenir ensuite...

  5. #5
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    Est que tu utilises bien une instance de ta classe ?
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Si les fonctions sont des méthodes de la classe, c'est normal qu'elles ne soient pas définies sur window.
    Voici un exemple où on appelle une fonction définie sur window et une fonction de la classe à partir des noms des fonctions :
    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
    <script>
    function fa() {
    		console.log("fa");
    }
     
    class Test {
    	constructor(nomFonctionDefinieSurWindow,nomFonctionDeLaClasse) {
    		window[nomFonctionDefinieSurWindow]();
    		this[nomFonctionDeLaClasse]();
    	}
    	fb() {
    		console.log("fb");
    	}
    }
     
    new Test("fa","fb");
    </script>
    La solution est donc d'écrire : var fn = this[fnstring](param);
    Suite à cette correction, de ce que j'ai vu, d'autres problèmes vont survenir ensuite...

    merci pour votre retour...maintenant que vous me l'expliquez ça paraît logique....je vais essayer avant de tomber sur la suite des problèmes...
    je suppose que cela va concerner la variable error ??

    c'est reparti

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 262
    Points : 121
    Points
    121
    Par défaut
    re,

    merci cela fonctionne et m'a permis de mieux comprendre.

    En effet, la suite des problème vient de la variable error.

    après quelques recherches j'ai trouvé une explication qui m'a bien aidée :

    https://sebastien-dupire.info/faire-...avascript.html

    du coup j'ai modifié mon code

    this.error = true;

    et dans ma méthode je l'a récupère avec :

    console.log(that.error).

    var name n'a qu'une portée dans la fonction elle-même alors que this.name elle devient accessible en dehors

    J'ai un doute sur la compréhension :
    var that = this;
    C'est en lisant que j'ai corrigé mais je ne suis pas sur de bien comprendre.

    est-ce parce que this renvoie à l'objet en-cours et que nous voulons récupérer un résultat en dehors de l'objet lui-même ???

    j'ai également lu que si on ne déclare pas une variable, elle appartient automatiquement à window.

    Si vous avez d'autres explications je suis plus que preneur pour ma progression

    Merci pour l'aide que vous m'avez apportée

  8. #8
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    var that = this;

    this est un pointeur local sur l'objet à l'intérieur de l'instance, that récupère ce pointeur , et that est global
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/06/2012, 17h08
  2. [JavaScript] [source]constructeur ou extension javascript poo ?
    Par SpaceFrog dans le forum Contribuez
    Réponses: 5
    Dernier message: 23/08/2010, 14h19
  3. [POO] Window pour lancer une fonction
    Par guy777 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 27/06/2008, 12h44
  4. Réponses: 2
    Dernier message: 14/08/2006, 22h12
  5. [ALERT]Javascript et window.location et moi
    Par kagura dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 26/07/2006, 17h46

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