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 :

prototype et __proto__


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    1 616
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 616
    Par défaut prototype et __proto__
    Bonjour

    une petite question aux spécialistes Javascript et de son modèle d'objets.

    Je me retrouve, je ne sais pas trop pourquoi, avec des objets instanciés sans prototype dans les propriétés de l'objet.

    Ce sont des "nodes" d'un arbre dynatree, un plug-in de Jquery

    https://code.google.com/p/dynatree/

    J'ai mis ici un fork des exemples de l'auteur, avec mes propres tests. Il faut ouvrir firebug sur la console pour voir les messages de test

    http://jsfiddle.net/eYFHh/4/

    Donc je souhaite étendre le prototype de cet objet node, avec une fonction me renvoyant son chemin complet jusqu'à la racine.
    Je ne souhaite pas modifier le source de dynatree pour ne pas avoir à reporter la modif sur les updates ultérieurs.

    Je veux pouvoir étendre le prototype du node à l'instanciation d'un arbre, en m'appuyant sur le rootnode qui existe même si l'arbre est vide, il est toujours là et invisible.

    Visiblement je n'ai pas d'objet prototype sur cet objet node, mais j'ai l'objet __proto__
    Il semble fonctionner de la même manière que prototype.

    Selon vous, est ce intelligent d'utiliser cet objet __proto__ ? risqué ?
    Y'a t'il d'autres méthodes ?

    Et pourquoi l'objet prototype n'est pas instancié ici, puisque visiblement ce serait juste un raccourci vers __proto__ ?

    Enfin bref, votre avis ? et suis-je sur la bonne voie pour la méthode ?

    Merci d'avance

    Fred

  2. #2
    Membre éprouvé
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Par défaut
    __proto__ est en fait l'instance "locale" du prototype à partir duquel un objet a été construit. En pratique une fonction a un prototype, un objet créé à partir d'un new cetteFonction() aura une propriété __proto__ pointant vers le prototype de la fonction.

    Je ne connais pas le plugin, mais en théorie une "instance" (variable assignée avec un new quelque-chose) aura l'attribut __proto__ pointant vers ce qui est "hérité" mais pas d'attribut prototype.
    Cet attribut prototype existe seulement pour les fonctions.

    Pour ta question modifier le __proto__ n'a pas tellement de sens car c'est juste un lien avec ce qui "hérité". Il faut modifier le prototype de la fonction constructeur qui est utilisée pour créer ta node, la modification sera alors "vue" par tous les objets pointant sur ce prototype (donc tous les nodes).

  3. #3
    Invité
    Invité(e)
    Par défaut
    Tu te mélanges les pinceaux

    Je te conseille de lire ça : http://msdn.microsoft.com/en-us/magazine/ff852808.aspx

    En fait, "protoype" est un attribut spécifique aux fonctions. Les fonctions possèdent un attribut prototype qui va devenir la propriété __proto__ des objets instanciés grâce à cette fonction (qui sera alors utilisée comme un constructeur).

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function Constructor() {};
    var instance = new Constructor();
    console.log(Constructor.prototype === instance.__proto__); // true

    J'espère être clair.

    EDIT : Remarque que la fonction a aussi un attribut __proto__ vu qu'une fonction est aussi un objet.
    EDIT2 : @ymoreau j'avais pas vu ta réponse. Un peu redondant du coup

  4. #4
    Membre actif
    Inscrit en
    Janvier 2008
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 64
    Par défaut
    Moi c'est avec ce post que j'ai appris :
    http://sporto.github.io/blog/2013/02...m_medium=email
    J'espere que ca t'aidera ^^

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    1 616
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 616
    Par défaut
    Merci

    Vos liens m'ont été fort utiles pour comprendre un peu mieux le fonctionnement de tout ça.

    Pour ta question modifier le __proto__ n'a pas tellement de sens car c'est juste un lien avec ce qui "hérité". Il faut modifier le prototype de la fonction constructeur qui est utilisée pour créer ta node, la modification sera alors "vue" par tous les objets pointant sur ce prototype (donc tous les nodes).
    Effectivement c'est ce qu'il faut faire.

    Dans le cas qui m'intéresse, il faut aller chercher le widget jquery UI dynatree qui semble exposer le constructeur et son prototype directement dans ses propriétés, sous un nom différent de celui que l'on lit dans le source de dynatree.
    En gros le prototype que je peux manipuler serait ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $.ui.dynatree._DynaTreeNodeClass.prototype
    Je présume que le widget factory de Jquery UI y est pour quelque chose. J'ai essayé de remonter ce dernier code pour comprendre mais j'ai pas encore vu la lumière. Pas trop de temps à passer là dessus

    Je présume que manipuler le prototype du constructeur par ce biais sera OK sur toutes les plateformes.

    J'aurai quand même bien une question :
    Est il possible à partir de l'instance d'un objet de remonter à son constructeur, et donc à son prototype ?
    J'ai bien vu : Object.getPrototypeOf(O)
    mais cela ne fonctionnerait pas sur IE de 6 à 8, et j'ai encore besoin de ces navigateurs.

    Y'a t'il d'autres méthodes plus universelles ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    La propriété "constructor" devrait t'être utile : elle pointe sur la fonction constructeur qui a été utilisée pour instancier l'objet.

    Exemple :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function Cls() {};
    var instance = new Cls();
    console.log(instance.constructor); // Cls
    console.log(instance.constructor.prototype === instance.__proto__); // true

    EDIT : apparemment bien supporté par IE depuis la version 6

  7. #7
    Membre Expert
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Par défaut
    Si le navigateur n'a pas getPrototypeOf , tu peux lui ajouter : (selon John Resig)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if ( typeof Object.getPrototypeOf !== "function" ) {
      if ( typeof "test".__proto__ === "object" ) {
        Object.getPrototypeOf = function(object){
          return object.__proto__;
        };
      } else {
        Object.getPrototypeOf = function(object){
          // May break if the constructor has been tampered with
          return object.constructor.prototype;
        };
      }
    }
    Il faut avoir conscience que object.constructor est mutable donc ce n'est pas une façon 100% fiable de vérifier, mais je ne pense pas qu'il en existe d'autres. Du moins, je ne l'ai jamais vu

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    1 616
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 616
    Par défaut
    oui effectivement, implémenté depuis le javascript 1.1 et ECMA1

    L'ayant vu dans des articles, j'avais regardé si je voyais cette propriété sur uun node avec un console.dir(), et non

    mais si je l'utilise pour référencer le constructeur et son prototype, cela fonctionne ...

    sauf que si j'affiche sous Firefox le constructor.name d'un noeud, je n'obtiens pas le nom de la fonction constructeur, mais Object, et donc quand je modifie le prototype, je modifie le prototype de Object.
    Je sais pas si c'est ce qu'il y a de mieux. Visiblement ça remonte jusqu'à la racine, puisque tout est objet en javascript

    Pour l'exemple Fiddle ci dessus, ça donne un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    console.log (typeof $("#tree").dynatree("getRoot")); //-->object
        console.log ($("#tree").dynatree("getRoot").constructor);//-->Object()
        console.log ($("#tree").dynatree("getRoot").constructor.name);//-->Object
        var one_node = $("#tree").dynatree("getTree").getNodeByKey("id3");
        var node_prototype = $("#tree").dynatree("getRoot").constructor.prototype;
        node_prototype.testproto = function(){return "test"}
        console.log (one_node.testproto());//-->test
        console.log (Object.testproto());//-->test
        console.dir (Object);//-->références à testproto () en boucle à l'infini ?
    il y a encore plein de trucs qui m'échappent dans le javascript

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

Discussions similaires

  1. [Prototype] Ajax avec paramètres
    Par Tail dans le forum Bibliothèques & Frameworks
    Réponses: 5
    Dernier message: 05/01/2006, 17h16
  2. [Prototype] Avoir plusieurs instances
    Par pedouille dans le forum Bibliothèques & Frameworks
    Réponses: 4
    Dernier message: 17/12/2005, 09h12
  3. [Prototype] Je ne comprends pas
    Par SpaceFrog dans le forum Bibliothèques & Frameworks
    Réponses: 30
    Dernier message: 15/12/2005, 10h59
  4. Réponses: 6
    Dernier message: 20/11/2005, 02h53
  5. Récupérer le prototype d'une fonction
    Par uaz dans le forum Général Python
    Réponses: 2
    Dernier message: 27/07/2004, 17h24

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