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 :

"POO" en JS


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 18
    Par défaut "POO" en JS
    Bonjour,
    je reprends le javascript après avoir longuement codé assez salement, je voudrais reprendre sur de bonnes bases.

    Après avoir cherché sur le net je voulais savoir si j'avais bien compris certaines choses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function classe (){
    var a = 1 ; -> privé
    this.b = 2 ; -> publique
    this.c = function(){}; ->publique
    var d = function(){}; ->privé
    function e(){};-> privé
    }
    (ici, non accessible ici par le constructeur)------
    classe.f = 3; ->attribut statique/publique

    classe.prototype.g=4; ->publique , ajouté à la classe et toutes les instances existantes ou non
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    classe.prototype.h = function(){}; -> publique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    instance = new classe();
    instance.a = 8; ->publique, propre à l'instance / redéfinition[/code]


    ------

    qlqs questions :
    1) est ce qu'il y a un meilleur moyen (plus propre) pour qu'une instance puisse atteindre le champ statique de sa classe que : classe.champStatic ?

    2) prototype est une super classe qui est vérifié lorsqu'un champ ou une méthode n'est pas trouvé dans la classe, mais je ne vois pas l’intérêt autre que de permettre d'ajouter un champ ou une méthode dynamiquement à une classe et ses instances.
    est ce que peut être le prototype d'une classe n'existe qu'une fois et une méthode qui n'existe pas dans un objet est cherché dans le prototype de la classe et donc là oui, on gagne en mémoire puisque non recopié dans chaque instance ?
    donc dans ce cas pourquoi ne pas tout mettre dans prototype ?

    3) qu'elle est la différence entre :
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var nom = function(){};
    à part que la 2eme est une fonction anonyme et les 2 privées ?

    merci pour les réponses

    j'espère ne pas avoir dit trop de stupidités

  2. #2
    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
    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 !

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 18
    Par défaut
    et bien oui j'ai vu, mais ça ne répond pas totalement à mes questions :/

  4. #4
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut
    Citation Envoyé par guive
    ça ne répond pas totalement à mes questions :/
    Peut-être que tu ne poses pas les bonnes questions

    Tu as utilisé 13 fois le mot "classe" dans ton post initial...

    Or.... les classes n'existent pas en JS. Tu peux réécrire ton post sans employer ce mot pour voir ?

    (ce que je veux dire, c'est que tant que tu essaieras de retrouver en JS des concepts qui lui sont étrangers parce que tu es plus à l'aise avec, tu vas t'arracher les cheveux... Profite de la vie, allez arrête de te faire du mal )

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 18
    Par défaut
    je le sais, c'est une façon de formaliser

  6. #6
    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
    voici ou j'en étais resté sur la POO en js
    http://www.developpez.net/forums/d96...avascript-poo/
    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 !

  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
    Citation Envoyé par guive Voir le message
    Bonjour,
    je reprends le javascript après avoir longuement codé assez salement, je voudrais reprendre sur de bonnes bases.

    Après avoir cherché sur le net je voulais savoir si j'avais bien compris certaines choses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function classe (){
    var a = 1 ; -> privé
    this.b = 2 ; -> publique
    this.c = function(){}; ->publique
    var d = function(){}; ->privé
    function e(){};-> privé
    }
    (ici, non accessible ici par le constructeur)------
    classe.f = 3; ->attribut statique/publique

    classe.prototype.g=4; ->publique , ajouté à la classe et toutes les instances existantes ou non
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    classe.prototype.h = function(){}; -> publique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    instance = new classe();
    instance.a = 8; ->publique, propre à l'instance / redéfinition[/code]


    ------

    qlqs questions :
    1) est ce qu'il y a un meilleur moyen (plus propre) pour qu'une instance puisse atteindre le champ statique de sa classe que : classe.champStatic ?

    2) prototype est une super classe qui est vérifié lorsqu'un champ ou une méthode n'est pas trouvé dans la classe, mais je ne vois pas l’intérêt autre que de permettre d'ajouter un champ ou une méthode dynamiquement à une classe et ses instances.
    est ce que peut être le prototype d'une classe n'existe qu'une fois et une méthode qui n'existe pas dans un objet est cherché dans le prototype de la classe et donc là oui, on gagne en mémoire puisque non recopié dans chaque instance ?
    donc dans ce cas pourquoi ne pas tout mettre dans prototype ?

    3) qu'elle est la différence entre :
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var nom = function(){};
    à part que la 2eme est une fonction anonyme et les 2 privées ?

    merci pour les réponses

    j'espère ne pas avoir dit trop de stupidités
    d'abord n'essaye pas de voir javascript comme un autre langage traditionnel. j'ai envie de dire qu'il est beaucoup plus souple et plus 'abstrait' (bon, j'invente un peu là )

    classe.f = 3; ->attribut statique/publique
    var classeObject = new classe();
    classeObject.f = 3;

    -> classe étant le nom de ta fonction (constructeur), classe.f rajoute un champ f à l'objet qu'est la fonction et non pas aux instances de cette fonction (constructeur).

    autrement classeObject.f rajoute/modifie le champ f de ton instance pour l'objet courant donné ! donc ne pas le définir dans le constructeur te permet de n'avoir un champ f que dans une seule de tes nombreuses instances par exemple. (sinon en général, il n'y a pas de "bonne" ou de "mauvaises" pratiques dans la conception de tes objets je dirai ...).

    1) avec ce que je dis juste ici au dessus, je ne suis pas sûr que la notion de statique soit à proprement parlé la bonne ici. ce que tu considères comme statique n'est qu'un champ "normal" de ton objet[fonction]

    2) prototype ne rajoute pas des champs s'ils ne sont pas trouvé ! ça rajoute des champs par défauts à ton objets tout simplement. ça ne rajoute pas des champs à une classe et ses instances mais uniquement aux instances de classe.

    le prototype n'existe effectivement qu'une fois à la base. il n'est pas "recherché" si la méthode n'existe pas dans l'objet. il est la méthode de l'objet par défaut. méthode de l'objet qui peut être remplacée par une autre par la suite.

    dans le cas d'une méthode :
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function classe1(){
      this.foo = function(){alert('foo');};
    }
     
    function classe2(){
    }
    classe2.prototype.foo = function(){alert('foo');};
    on prétend souvent que le prototype permet de ne pas dupliquer les méthodes par exemple, comme ci dessus. Où les champs "foo" des instances de la classe2 pointeront tous vers une unique fonction en mémoire. tandis que les champs "foo" des instances de classe1 pointeront chacun vers une nouvelle fonction créée en même temps que l'instance.

    cette différence étant évidement "bidon", puisque l'équivalent de la classe2 serait simplement :
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var foo = function(){alert('foo');};
    function classe1(){
      this.foo = foo;
    }
     
    function classe2(){
    }
    classe2.prototype.foo = function(){alert('foo');};
    dans ce cas, les champs "foo" de toutes les instances de la "classe1" pointeront eux aussi vers une unique fonction "foo" en mémoire.

    en général les gens utiliseront surtout le prototype pour "éclaircir" le constructeur en mettant toutes les "définitions" en dehors de celui-ci. le constructeur ne contenant plus qu'une éventuelle "exécution" de code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function classe2(){
      init(this);
    }
    classe2.prototype.x = 2;
    classe2.prototype.y = 4;
    classe2.prototype.foo = foo;
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function classe1(){
      init(this);
      this.x = 2;
      this.y = 4;
      this.foo = foo; 
    }
    ici les résultat seront exactement pareils. ( à l'exception des "objets" prototypes qui seront différent évidement)

    sinon pour revenir à la déclaration de fonctions (dupliquées) dans une "classe", cela à pour avantage d'avoir accès aux variables privées d'une "classe". par exemple :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function classe2(){
      var priv = 42;
      this.foo =  function(){alert(priv);};
    }
    qui ne pourra pas fonctionner dans les 2 cas précédents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var foo = function(){alert(priv);};
    function classe1(){
      var priv = 42;
      this.foo =  foo;
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function classe1(){
      var priv = 42;
    }
    classe1.prototype.foo = function(){alert(priv);};
    venons-en maintenant à la réelle différence entre les 2 types de déclarations (en dehors du coté "épurer le constructeur de toutes déclarations").

    on peut créer 2 classes avec le même prototype :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function classe1(){};
    classe1.prototype.a = 1;
    classe1.prototype.b = 2;
    classe1.prototype.c = 3;
    functino classe2(){};
    classe2.prototype = classe1.prototype;
    ici, toutes les instances de classe1 et de classe2 auront des champs a,b et c.

    attention toutefois, le prototype des 2 classes étant ici un objet unique, si tu modifies celui d'une des 2 classes, tu modifies les 2. par exemple :
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    classe2.prototype.a = 99;
    alert(classe1.prototype.a); // 99

    d'ailleurs fait aussi attention avec les prototype contenant des objets car comme pour les méthodes, il n'y en aura qu'un en mémoire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function classe1(){}
    classe1.prototype.data = {};
    var obj1 = new classe1(), obj2 = new classe1();
    obj1.data.a = 1;
    alert(obj2.data.a); // 1
    et pour finir, je t'offre ce petit code pour t'amuser :
    Code js : 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
    var myPrototype = {a:1,b:2,c:3};
     
    function copyAllField(obj){ 
    	for(var i in obj) 
    		this[i]=obj[i]; 
    };
    function displayAllField(){ 
    	var s = ''; 
    	for(var i in this) 
    		s+=i+"="+this[i].toString()+", ";
    	alert(s.substr(0,s.length-2));
    }
     
    Function.prototype.setPrototype = function(proto){
    	this.prototype = proto; // ecrase le précédent prototype
    	this.prototype.addPrototype = copyAllField; 
    	this.prototype.display = displayAllField; 
    };
     
    function foo(){
    	this.addPrototype({d:4});
    }
    foo.prototype.champQuiSeraEcraseALaProchaineLigne = 123456789;
    foo.setPrototype(myPrototype);
    foo.prototype.e = 5;
     
    var obj = new foo();
    obj.display();

    3) la différence entre
    var a = function(){} et function a(){}
    est déjà que dans certains navigateurs (chrome et firefox mais pas IE) il existe l'attribut "name" aux fonctions, donc tu pourras avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function afficheNom(func){
      alert(func.name); // affichera "b" dans cet exemple (sous chrome et firefox)
    }
    function b(){}
    var a = b;
    afficheNom(a);
    mais pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function afficheNom(func){
      alert(func.name);
    }
    var a = function(){}
    afficheNom(a);
    à part ça, les 2 reviennent quasi au même j'ai envie de dire hormis p-e une lisibilité différente car dans un cas tu liras en premier "oh une déclaration de fonction" et dans l'autre cas tu verras d'abord le nom de la variable. bref : Il n'y a pas de "bonne" ou de "mauvaise" ...


    edit: il y a surement des erreurs(ou au moins de précision à apporter) dans(à) ce que je dis, je laisse mes collègues me corriger.

  8. #8
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 207
    Par défaut
    je ne saurais te recommander également, si cela n'est déjà fait, les cours sur la Programmation objet, sur ce site même que j'ai trouvé bien fait...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 18
    Par défaut
    merci beaucoup pour tes réponses, qui sont exactement celle que je recherchais

    j'ai eu beau lire, mais souvent les articles sont incomplets etc...

    merci en tout cas

    ps : j'ai pas vu les articles sur la poo j'ai cherché partout sur le net sauf ici, honteux, mais les réponses que j'ai eu ici me sont suffisantes

  10. #10
    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 voulant tester s'il n'y avait pas de différence de temps pour :
    et
    étant donné que le premier exécute en fait 2 instructions (une déclaration de fonction anonyme + une asignation) ma curiosité m'a démontre que non, le temps d'éxecution sont vraiment égaux(ou différence suffisament insignifiante) mais par contre en faisant mes tests j'ai remarqué que chrome était 6 fois plus lent que ie ou firefox pour executer une boucle de déclaration de fonctions.... je suis choqué ! moi qui vénérait chrome

  11. #11
    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 Willpower Voir le message
    en voulant tester s'il n'y avait pas de différence de temps pour :
    et
    étant donné que le premier exécute en fait 2 instructions (une déclaration de fonction anonyme + une asignation) ma curiosité m'a démontre que non, le temps d'éxecution sont vraiment égaux(ou différence suffisament insignifiante) mais par contre en faisant mes tests j'ai remarqué que chrome était 6 fois plus lent que ie ou firefox pour executer une boucle de déclaration de fonctions.... je suis choqué ! moi qui vénérait chrome
    je viens de faire une seconde batterie de tests et j'obtiens des résultats totalement différents :

    par rapport à
    la code suivant dure :
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a = function(){}// avec var a déclaré préalablement
    ff: 1x aussi rapide
    chrome : 25x plus lent
    ie : 35x plus lent
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var a = function(){}// avec var a déclaré préalablement ou non
    ff: 0,2x plus lent (= 5 fois plus rapide)
    chrome : 25x plus lent
    ie : 35x plus lent
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    window.a = function(){}// avec var a déclaré préalablement
    ff: 3x plus lent
    chrome : 95x plus lent
    ie : 35x plus lent
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    window.a = function(){}// avec var a non déclaré préalablement
    ff: 2x plus lent
    chrome : 95x plus lent
    ie : 130x plus lent
    ---------------------


    testé avec le code suivant :
    Code js : 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
    function compare(fn1,fn2){
    	var max_delay = 200,
    	nbr_test = 7;
    	//
    	var tab1=[],tab2=[],iter=1,delay=0,median=Math.round(nbr_test/2),time=new Date().getTime();
    	while(delay<max_delay){
    		for(var j=(iter*=2);j>0;j--){
    			fn1();
    			fn2();
    		}
    		delay = -time+(time = new Date().getTime());
    	}
    	for(;nbr_test>0;nbr_test--){
    		// test fn1
    		time = new Date().getTime();
    		for(var j=iter;j>0;j--)
    			fn1();
    		tab1.push(-time+(time=new Date().getTime()));
    		// test fn2
    		time = new Date().getTime();
    		for(var j=iter;j>0;j--)
    			fn2();
    		tab2.push(-time+(time=new Date().getTime()));
    	}
    	tab1.sort(function(a,b){return a-b;});
    	tab2.sort(function(a,b){return a-b;});
    	//alert(tab1 + " // " + tab2);
    	return (tab1[median]/tab2[median]);
    }
     
    	function f11(u){
    		for(var i=0;i<1000;i++)
    			var a = function(){};
    	}
    	function f22(u){
    		for(var i=0;i<1000;i++)
    			function a(){};
    	}
    	alert("ration (!u)/(u==undefined) : "+Math.round(compare(f11,f22)*100)+"% (1/ratio = "+Math.round(compare(f22,f11)*100)+"%)");


    donc j'aurai tendance à généraliser que
    est plus rapide qu'une assignation de fonction anonyme (dans la majorité des cas) mais je maintiens que la principale différence des 2 sera principalement au niveau de la lisibilité. par exemple ceux habitués à utiliser des objets (genre json etc..) auront pour habitude de faire leurs déclaration ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var obj = {
       myProperty : "ceci est un string",
       myFunction : function(){},
       myObject : {}
    }
    ils auront donc tendance (j'imagine) à écrire leurs fonctions (en dehors d'objets) de la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var myFunction = function(){}


    oui, je m'emmerde vraiment pour écrire tout ça.

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

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