[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/function-prototype [Back]  [Original]

F.prototype
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Rappelez-vous que de nouveaux objets peuvent tre crs avec une fonction constructeur, comme new F().

    Si F.prototype est un objet, alors loprateur new lutilise pour dfinir [[Prototype]] pour le nouvel objet.

    Veuillez noter

    JavaScript avait lhritage prototypique depuis le dbut. Ctait lune des caractristiques principales du langage.

    Mais dans le pass, il ny avait pas daccs direct. La seule chose qui fonctionnait de manire fiable est une proprit "prototype" de la fonction constructeur dcrite dans ce chapitre. Donc, il y a beaucoup de scripts qui lutilisent encore.

    Veuillez noter que F.prototype signifie ici une proprit rgulire nomme "prototype" sur F. Cela ressemble quelque peu au terme prototype, mais nous entendons ici une proprit rgulire portant ce nom.

    Voici lexemple :

    let animal = {
      eats: true
    };
    
    function Rabbit(name) {
      this.name = name;
    }
    
    Rabbit.prototype = animal;
    
    let rabbit = new Rabbit("White Rabbit"); //  rabbit.__proto__ == animal
    
    alert( rabbit.eats ); // true

    Dfinir Rabbit.prototype=animal nonce littralement ce qui suit : Lorsquun new Rabbit est cr, assigner son [[Prototype]] animal.

    Voici limage rsultante :

    []

    Sur limage, "prototype" est une flche horizontale, ce qui signifie une proprit normale, et [[Prototype]] est vertical, ce qui signifie lhritage de rabbit de animal.

    F.prototype utilis uniquement pendant new F

    La proprit F.prototype est utilise uniquement lorsque new F est appel, elle attribue [[Prototype]] du nouvel objet. Aprs cela, il ny a plus de connexion entre F.prototype et le nouvel objet.

    Si, aprs la cration, la proprit F.prototype change (F.prototype = <un autre objet>), les nouveaux objets crs par new F auront un autre objet comme [[Prototype]], mais les objets dj existants conservent lancien.

    F.prototype par dfaut, proprit du constructeur

    Chaque fonction a la proprit "prototype" mme si nous ne la fournissons pas.

    Le "prototype" par dfaut est un objet avec comme seule proprit constructor qui renvoie la fonction elle-mme.

    Comme a :

    function Rabbit() {}
    
    /* prototype par dfaut
    Rabbit.prototype = { constructor: Rabbit };
    */
    []

    Nous pouvons le vrifier :

    function Rabbit() {}
    // par dfaut:
    // Rabbit.prototype = { constructor: Rabbit }
    
    alert( Rabbit.prototype.constructor == Rabbit ); // true

    Naturellement, si nous ne faisons rien, la proprit constructor est disponible pour tous les rabbits via [[Prototype]] :

    function Rabbit() {}
    // par dfaut:
    // Rabbit.prototype = { constructor: Rabbit }
    
    let rabbit = new Rabbit(); // hrite de {constructor: Rabbit}
    
    alert(rabbit.constructor == Rabbit); // true (de prototype)
    []

    Nous pouvons utiliser la proprit constructor pour crer un nouvel objet en utilisant le mme constructeur que lexistant.

    Comme ici :

    function Rabbit(name) {
      this.name = name;
      alert(name);
    }
    
    let rabbit = new Rabbit("White Rabbit");
    
    let rabbit2 = new rabbit.constructor("Black Rabbit");

    Cest pratique lorsque nous avons un objet, ne sachant pas quel constructeur a t utilis pour cela (par exemple, il provient dune bibliothque externe), et nous devons en crer un autre du mme type.

    Mais probablement la chose la plus importante propos de "constructor" est que

    JavaScript lui-mme nassure pas la bonne valeur de "constructor".

    Oui, il existe dans le "prototype" par dfaut des fonctions, mais cest tout. Ce quil en adviendra par la suite dpend entirement de nous.

    En particulier, si nous remplaons le prototype par dfaut dans son ensemble, il ne contiendra pas de constructor.

    Par exemple :

    function Rabbit() {}
    Rabbit.prototype = {
      jumps: true
    };
    
    let rabbit = new Rabbit();
    alert(rabbit.constructor === Rabbit); // false

    Donc, pour garder le bon "constructor", nous pouvons choisir dajouter/supprimer des proprits au "prototype" par dfaut au lieu de lcraser dans son ensemble :

    function Rabbit() {}
    
    // Ne pas craser Rabbit.prototype totalement
    // juste y ajouter
    Rabbit.prototype.jumps = true
    // le Rabbit.prototype.constructor par dfaut est conserv

    Ou bien, recrez manuellement la proprit constructor :

    Rabbit.prototype = {
      jumps: true,
      constructor: Rabbit
    };
    
    // maintenant le constructeur est galement correct, car nous l'avons ajout

    Rsum

    Dans ce chapitre, nous avons brivement dcrit la manire de dfinir un [[Prototype]] pour les objets crs via une fonction constructeur. Plus tard, nous verrons des modles de programmation plus avancs qui en dpendent.

    Tout est assez simple, juste quelques prcisions pour clarifier les choses :

    • La proprit F.prototype (ne pas confondre avec [[Prototype]]) dfinit [[Prototype]] sur les nouveaux objets lorsque new F() est appele.
    • La valeur de F.prototype devrait soit tre un objet ou null : les autres valeurs ne fonctionneront pas.
    • La proprit "prototype" na cet effet spcial que lorsquelle est dfinie dans une fonction constructeur et invoque avec new.

    Sur les objets ordinaires, le prototype na rien de spcial :

    let user = {
      name: "John",
      prototype: "Bla-bla" // pas de magie
    };

    Par dfaut, toutes les fonctions ont F.prototype={constructor:F}, nous pouvons donc obtenir le constructeur dun objet en accdant sa proprit "constructor".

    Exercices

    importance: 5

    Dans le code ci-dessous, nous crons new Rabbit, puis essayons de modifier son prototype.

    Au dbut, nous avons ce code :

    function Rabbit() {}
    Rabbit.prototype = {
      eats: true
    };
    
    let rabbit = new Rabbit();
    
    alert( rabbit.eats ); // true
    1. Nous avons ajout une chane de caractres supplmentaire (surligne), quaffiche alert maintenant ?

      function Rabbit() {}
      Rabbit.prototype = {
        eats: true
      };
      
      let rabbit = new Rabbit();
      
      Rabbit.prototype = {};
      
      alert( rabbit.eats ); // ?
    2. Et si le code est comme a (une ligne remplace) ?

      function Rabbit() {}
      Rabbit.prototype = {
        eats: true
      };
      
      let rabbit = new Rabbit();
      
      Rabbit.prototype.eats = false;
      
      alert( rabbit.eats ); // ?
    3. Et comme ceci (une ligne remplace) ?

      function Rabbit() {}
      Rabbit.prototype = {
        eats: true
      };
      
      let rabbit = new Rabbit();
      
      delete rabbit.eats;
      
      alert( rabbit.eats ); // ?
    4. La dernire variante :

      function Rabbit() {}
      Rabbit.prototype = {
        eats: true
      };
      
      let rabbit = new Rabbit();
      
      delete Rabbit.prototype.eats;
      
      alert( rabbit.eats ); // ?
    solution

    Rponses :

    1. true.

    Laffectation Rabbit.prototype configure [[Prototype]] pour les nouveaux objets, mais naffecte pas les objets existants.

    1. false.

    Les objets sont assigns par rfrence. Lobjet de Rabbit.prototype nest pas dupliqu, mais un objet unique est rfrenc la fois par Rabbit.prototype et par le [[Prototype]] de rabbit.

    Ainsi, lorsque nous modifions son contenu par lune des rfrences, il est visible par lautre.

    1. true.

    Toutes les oprations delete sont appliques directement lobjet. delete rabbit.eats tente ici de supprimer la proprit eats de rabbit, mais ne la pas. Donc lopration naura aucun effet.

    1. undefined.

    La proprit eats est supprime du prototype, elle nexiste plus.

    importance: 5

    Imaginez nous avons un objet arbitraire obj, cr par une fonction constructeur nous ne savons pas lequel, mais nous aimerions crer un nouvel objet laide de celui-ci.

    Pouvons-nous le faire comme a ?

    let obj2 = new obj.constructor();

    Donne un exemple de fonction constructeur pour obj qui laisse ce code fonctionner correctement. Et un exemple qui fait que a marche mal.

    solution

    Nous pouvons utiliser cette approche si nous sommes srs que la proprit "constructeur" a la valeur correcte.

    Par exemple, si nous ne touchons pas le "prototype" par dfaut, alors ce code fonctionne coup sr :

    function User(name) {
      this.name = name;
    }
    
    let user = new User('John');
    let user2 = new user.constructor('Pete');
    
    alert( user2.name ); // Pete (a marche !)

    Cela a fonctionn, car User.prototype.constructor == User.

    Mais si quelquun, pour ainsi dire, crase User.prototype et oublie de recrer constructor pour faire rfrence User, il chouera.

    Par exemple :

    function User(name) {
      this.name = name;
    }
    User.prototype = {}; // (*)
    
    let user = new User('John');
    let user2 = new user.constructor('Pete');
    
    alert( user2.name ); // undefined

    Pourquoi user2.name est undefined ?

    Voici comment new user.constructor('Pete') fonctionne :

    1. Tout dabord, il cherche constructor dans user. Rien.
    2. Ensuite, il suit la chane de prototypes. Le prototype de user est User.prototype, et il na pas non plus de constructor (parce que nous avons oubli de le rgler correctement!).
    3. En remontant la chane, User.prototype est un objet simple, son prototype est le Object.prototype intgr.
    4. Enfin, pour le Object.prototype intgr, il existe un Object.prototype.constructor == Object intgr. Il est donc utilis.

    En fin de compte, nous avons let user2 = new Object('Pete').

    Ce nest probablement pas ce que nous voulons. Nous aimerions crer un new user, pas un new Object. Cest le rsultat du constructor manquant.

    (Juste au cas o vous seriez curieux, lappel new Object(...) convertit son argument en un objet. Cest une chose thorique, en pratique personne nappelle new Object avec une valeur, et gnralement nous nutilisons pas new Object pour crer des objets).

    Carte du tutoriel

    Commentaires

    lire ceci avant de commenter
    • Si vous avez des amliorations suggrer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
    • Si vous ne comprenez pas quelque chose dans l'article, merci de prciser.
    • Pour insrer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page