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 :

[partage] héritage de classes


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 [partage] héritage de classes
    Bonjour à tous. :-)
    (mon premier poste)

    J'ai décidé, il y a quelques jours, de créer de l'héritage en javascript. (juste pour le fun, car aucune utilité apparente.) J'ai donc commencé par chercher les différentes version existantes sur la toile mais celles que j'ai trouvé semblaient "mal" fonctionner. Je me suis donc dis que je pouvais m’atteler à la tâche sans craindre de refaire ce qui existe déjà.

    Bref, voici mon code (qui devra certainement être amélioré).

    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
     
    function searchInArray(arr,elem) {   
        if (Array.prototype.indexOf)  return arr.indexOf(elem); 
        for (var i in arr) if (arr[i] === elem)  return i;   
        return -1;   
    }  
     
    function __uber(fname,arg){ 
        var c = arguments.callee; 
        while(c.caller != null && typeof(c.caller.from)=="undefined") 
            c = c.caller;     
        if(c.caller!=null) 
            var parentIndex = searchInArray(this.constructor.herited,c.caller.from)-1; 
        else 
            var parentIndex = this.constructor.herited.length-1;     
        while(parentIndex>=0 && !this.parentFN[this.constructor.herited[parentIndex]]  )  
            parentIndex--; 
        if(parentIndex < 0)  
            throw fname+"() not found in parent constructors of current object."; 
        var func = this.parentFN[this.constructor.herited[parentIndex]][fname]  ; 
        var arg = arg || []; 
        return func.apply(this,arg); 
    }
     
    function __construct(obj){ 
    	if(__construct.caller!=obj.constructor) return; // prevent from recursive calls
        for(var i=0;i<obj.constructor.herited.length;i++){// for(var i in obj.constructor.herited) will call Array.prototype and Object.prototype functions
            try{ obj.constructor.herited[i].apply(obj,__construct.caller.arguments); } 
                catch(err) { throw "error to calling parent constructor : "+i+" ["+err+"]"; } 
            try{ __copyFunctions(obj,obj.constructor.herited[i]); } 
                 catch(err) { throw "error to copying parent functions of : "+i+" ["+err+"]"; } 
        } 
    }
     
    function __copyFunctions(obj,constructorParent){ 
        obj.parentFN = obj.parentFN || {}; 
        obj.parentFN[constructorParent] = {}; 
        for(var i in obj) if(typeof(obj[i])=='object' || typeof(obj[i])=='function'){ 
            obj.parentFN[constructorParent][i] = obj[i]; 
            obj.parentFN[constructorParent][i].from = constructorParent;  
        } 
    }
     
    Function.prototype.inherits = function(Parent){ 
        if(this.herited) 
            eval("var newF = "+this.toString()); // newF = clone( this ); -> change on newF.prototype will not affect this.prototype 
        else{ 
            var s = this.toString(); 
            var b = s.indexOf("{")+1; 
            eval("var newF = "+s.substring(0,b)+"__construct(this);"+s.substring(b,s.length)); 
        } 
        for(var i in Parent.prototype)  
            newF.prototype[i] = Parent.prototype[i];  
        for(var i in this.prototype)  
            newF.prototype[i] = this.prototype[i]; 
        newF.herited = (this.herited?this.herited.slice(0):[]); 
        var H = (Parent.herited?Parent.herited.slice(0):[]) //  = parent.herited[] 
        H.push(Parent); //  = parent.herited[] + parent 
        newF.herited = H.concat(newF.herited) //  = parent.herited[] + parent + this.herited[] 
        newF.name = newF.name || this.toString().substring(9,this.toString().indexOf('(')); // define Function.name property for IE  || it's useless
        //\\ this.name =  this.name || this.toString().substring(9,this.toString().indexOf('('));
    	//\\ if(this.name!="(")  // the next line will don't work on unamed function 
        //\\ 	eval(this.name+" = newF"); // uncomment thoses lines to overwrite "this" function, then when you call B.inherits(A) that'll make : B = newF;  
    	newF.prototype.uber = __uber;
        return newF; 
    };
    Et voici un bout de code pour le tester sommairement :
    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
    var alert = function(val){document.write(val,"<hr>");};
     
    function A(){this.a=1;this.aa=function(){alert("aa");};this.obj={val:97};this.hard=function(c){alert("a.hard: "+c);};} 
    A.prototype.fun = 11;
    function B(name){this.b=2;this.bb=function(){alert("bb");};this.name=name;this.hard=function(v){alert("b.hard: "+v);this.uber("hard",arguments);};} 
    function O(){this.o=3;this.oo=function(){alert("oo");};} 
    function H(){this.h=4;this.aa=function(){alert("hh");};this.oo=function(){alert("hh");};} 
    H.prototype.fun = 22;
    var B = B.inherits(A); 
    var H = H.inherits(B); 
    var H = H.inherits(O); 
     
    var h = new H("john smith"); 
     
     
     
    alert("=============== FOR EACH IN ( h ) ===============");
    for(var i in h)    alert(i+": "+h[i]); 
    // a: 1 
    // b: 2 
    // o: 3 
    // h: 4 
    // func aa : alert hh 
    // func bb : alert bb 
    // func oo : alert hh 
    // parentFN :  ############### object
    // obj :    object
    // name : "john smith" 
    // uber :  ############# function
     
    // overwrited functions 
    alert("=============== OVERWRITED FUNCTIONS ===============");
    h.aa(); // hh  
    h.oo(); // hh 
    alert("=============== SUPER/ORIGINAL FUNCTIONS ===============");
    // super functions who been overwrited 
    h.uber("aa"); // aa 
    h.uber("oo"); // oo 
    alert("=============== HERITED FUNCTIONS ===============");
    // herited function 
    h.bb(); // bb 
    alert("=============== OBJECTS FROM 2 DIFFERENT INSTANCES ===============");
    // test if object1.obj != object2.obj
    var h2 = new H(); 
    h2.obj.val++; 
    alert(h2.obj.val); // 98 
    alert(h.obj.val); // 97 
    alert("=============== PARENTS PROTOTYPE AREN'T MODIFIED ON CHANGE OF CHILD PROTOTYPE ===============");
    var a = new A();
    alert(a.fun);
    alert(h.fun);
    alert("=============== FINAL TEST ===============");
    h.hard("Happy End");

    Voila, j'attend vos opinions avec impatience : Ca ne sert à rien ? Ca ne fonctionne pas ? Ca existe deja ? C'est une bonne idée à améliorer ? Suggestions ?

    Bonne lecture et merci pour votre attention.



    PS: code peu commenté mais j'ai essayé de le faire lisible .. puis y'a les tests pour le resultat. Car c'est ce qui compte in fine.

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

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    ça existe déjà

    il existe des dizaines d'implémentations de la notion de classes en javascript

    je rappelle que JS est un langage à objet orienté prototype
    et l'exploitation de cette caractéristique est très efficace alors plutôt que réinventer la roue je t'invite à comprendre et à manipuler la notion de prototype tu découvrira que nombre de notion introduite avec les langages à objet orienté classe n'ont pas de raison d'être en javascript car le langage offre des solutions simples et élégantes.

    combiné au fait que js est un langage dynamique on obtient des capacités étonnantes

    A+JYT

  3. #3
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 659
    Billets dans le blog
    1
    Par défaut
    rien que ça j'en ai des boutons ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var alert = function(val){document.write(val,"<hr>");};
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  4. #4
    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
    Citation Envoyé par sekaijin Voir le message
    ça existe déjà

    il existe des dizaines d'implémentations de la notion de classes en javascript

    je rappelle que JS est un langage à objet orienté prototype
    et l'exploitation de cette caractéristique est très efficace alors plutôt que réinventer la roue je t'invite à comprendre et à manipuler la notion de prototype tu découvrira que nombre de notion introduite avec les langages à objet orienté classe n'ont pas de raison d'être en javascript car le langage offre des solutions simples et élégantes.

    combiné au fait que js est un langage dynamique on obtient des capacités étonnantes

    A+JYT
    Tous les exemples qu'ils m'aient été donné de trouver sur le net étaient plus que primaires, ne copiaient pas les objets de l'objet (juste des référence), instancié des objet parent pour copier des prototype alors qu'aucun objet enfant n'était instancié, des problèmes avec "instanceof" et moultes autres bugs selon les version. (et pour les rares qui implémentent la fonction uber/super ... elle avait souvent du mal dès l'héritage de plus d'une classe).



    Citation Envoyé par SpaceFrog Voir le message
    rien que ça j'en ai des boutons ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var alert = function(val){document.write(val,"<hr>");};
    heu .... en même temps, c'est juste dans la partie "test". (facebook aussi redéfini "alert").




    bref, j'ai complètement retravaillé/nettoyé ma classe dont voici une nouvelle version : (ils manquent encore qqes trucs et n'est peut-être pas encore parfaite mais voilà)

    http://www.borisdessy.com/

    Merci d'avance pour vos avis/suggestions/améliorations.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juillet 2010
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 96
    Par défaut
    tu serait surement intéressé a jeter un coup d'oeil a http://javascript.crockford.com/inheritance.html

  6. #6
    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
    Citation Envoyé par nault Voir le message
    tu serait surement intéressé a jeter un coup d'oeil a http://javascript.crockford.com/inheritance.html
    oui, une des versions les moins pourris que j'ai trouvé sur la toile, je ne me rappelle plus de tous les bugs mais déjà test :

    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function A(){this.obj = {val:1};alert("do something here");}
    function B(){}
    B.inherits(A);
     
    var b1 = new B();
    var b2 = new B();
     
    b1.obj.val++;
    alert(b2.obj.val); // 2 -> au lieu de 1

    ça instancie un seul objet A .... pour les 2 objets B
    et si on n'instanciait aucun objet B .. ça instancierait malgré tout un objet A

    et il me semble qu'il y avait aussi des bugs avec la fonction "uber" sur l'heritage de plus d'une classe ... mais j'ai plus ça en tête.

    edit:
    http://www.borisdessy.com/
    vs
    http://www.borisdessy.com/crock.html

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

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Par défaut
    Citation Envoyé par Willpower Voir le message
    heu .... en même temps, c'est juste dans la partie "test". (facebook aussi redéfini "alert").
    ce n'est pas la redéfinition d'alert qui donne des boutons c'est utiliser document.write


    A+JYT

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

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205

Discussions similaires

  1. [Python 2.X] Mauvaise compréhension du partage d'attributs en héritage de classes
    Par Chello dans le forum Général Python
    Réponses: 6
    Dernier message: 19/07/2014, 14h46
  2. Héritage de classes.
    Par Berzerk_ dans le forum C++
    Réponses: 48
    Dernier message: 13/08/2006, 23h48
  3. [POO] Héritage vs classe dans une classe
    Par robichou dans le forum Langage
    Réponses: 4
    Dernier message: 06/08/2006, 23h51
  4. attribut partagé d'une classe
    Par tanjonaravelson dans le forum Général Python
    Réponses: 3
    Dernier message: 27/09/2005, 16h26
  5. [OO] Héritage - Mixins Classes
    Par djmalo dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 01/03/2005, 23h16

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