Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
Object.prototype.__proto__
Obsolète: Cette fonctionnalité n'est plus recommandée. Même si certains navigateurs la prennent encore en charge, elle a peut-être déjà été supprimée des standards du web, est en passe d'être supprimée ou n'est conservée qu'à des fins de compatibilité. Évitez de l'utiliser et mettez à jour le code existant si possible ; consultez letableau de compatibilité au bas de cette page pour vous aider à prendre votre décision. Sachez que cette fonctionnalité peut cesser de fonctionner à tout moment.
Attention :Étant donnée la façon dont la plupart des moteurs JavaScript optimisent les performances, modifier le[[Prototype]] d'un objet est une opération lente pour chaque navigateur et moteur JavaScript. Les impacts liés aux performances sur ce point sont vastes et subtiles : ils concernent pas uniquement le temps passé à effectuerobj.__proto__ = ..., mais peuvent concerner n'importe quel code pour n'importe quel objet dont[[Prototype]] a été modifié. Si vous souhaitez obtenir des performances optimales, évitez de modifier le[[Prototype]] d'un objet. À la place, il est conseillé de créer un objet avec le prototype voulu en utilisantObject.create().
Attention :Bien que la propriétéObject.prototype.__proto__ soit déjà supportée dans la plupart des navigateurs à l'heure actuelle, son comportement n'a été standardisé que récemment avec la spécification ECMAScript 2015. Si vous avez besoin d'utiliser cette propriété dans des environnements antérieurs à ES2015, il est recommandé d'utiliserObject.getPrototypeOf().
La propriété__proto__ deObject.prototype est une propriété accesseur (un couple de fonction avec un accesseur (getter) et un mutateur (setter)) qui expose le[[Prototype]] interne (qui est soit un objet, soitnull) de l'objet courant.
L'utilisation de__proto__ est sujet à controverse. Elle a été déconseillée par plusieurs personnes et n'avait jamais été incluse dans la spécification ECMAScript. Cependant, de nombreux navigateurs ont décidé de l'implémenter. À l'heure actuelle, la propriété__proto__ a été standardisée avec la spécification ECMAScript 2015 et sera officiellement supportée à l'avenir. Une alternative à cette propriété peut être l'utilisation des méthodesObject.getPrototypeOf/Reflect.getPrototypeOf etObject.setPrototypeOf/Reflect.setPrototypeOf. Cependant, modifier le[[Prototype]] d'un objet est toujours une opération lente qui doit être évitée le plus possible pour des raisons de performances.
La propriété__proto__ peut également être utilisée avec un littéral objet afin de définir le[[Prototype]] lors de la construction (ce qui en fait une alternative àObject.create(). Voir la page surles initialisateurs d'objet.
Dans cet article
Syntaxe
var proto = obj.__proto__;Note :Le nom de la propriété est composé de deux tirets bas, suivis de « proto », suivis par deux tirets bas (underscores)
Description
L'accesseur__proto__ expose la valeur du[[Prototype]] interne d'un objet.
- Pour les objets créés via un littéral objet, cette valeur est
Object.prototype. - Pour les objet créés via un littéral de tableau, cette valeur est
Array.prototype. - Pour les fonctions, cette valeur est
Function.prototype. - Pour les objets créés en utilisant
new fun, avecfunun des constructeurs natif de fonctions, fournis par JavaScript (Array,Boolean,Date,Number,Object,String, etc.), cette valeur estfun.prototype. - Pour les objets créés en utilisant
new fun, avecfunune function definie dans un script, cette valeur est la valeur defun.prototypeau moment oùnew funest évaluée. (Ainsi, si on affecte une nouvelle valeur àfun.prototype, les instances crées précédemment conserveront leur[[Prototype]], les objets créés par la suite bénéficieront de la nouvelle valeur pour leur[[Prototype]].)
Le mutateur__proto__ permet de changer le[[Prototype]] d'un objet. Cet objet doit être extensible selonObject.isExtensible, si ce n'est pas le cas, une exceptionTypeError sera renvoyée. La valeur fournie pour le nouveau prototype doit être un objet ounull. Toute autre valeur entraînera un échec silencieux.
Pour plus d'éléments sur le fonctionnement de l'héritage et des prototypes, voir la page surl'héritage et les chaînes de prototypes.
Le propriété__proto__ n'est qu'une propriété accesseur (composée d'une fonction accesseur (getter) et d'une fonction mutateur (setter)) pourObject.prototype. Si l'accès à__proto__ consulteObject.prototype, on trouvera la propriété. Un accesseur qui ne consulte pasObject.prototype ne pourra pas trouver le prototype. Si une propriété__proto__ est trouvée avant queObject.prototype ne soit consulté, cette propriété « cachera »Object.prototype.
var aucunProto = Object.create(null);console.log(typeof aucunProto.__proto__); // undefinedconsole.log(Object.getPrototypeOf(aucunProto)); // nullaucunProto.__proto__ = 17;console.log(aucunProto.__proto__); // 17console.log(Object.getPrototypeOf(aucunProto)); // nullvar protoCaché = {};Object.defineProperty(protoCaché, "__proto__", { value: 42, writable: true, configurable: true, enumerable: true,});console.log(protoCaché.__proto__); // 42console.log(Object.getPrototypeOf(protoCaché) === Object.prototype); // trueExemples
Dans ce qui suit, on crée un nouvelle instance d'Employé et on teste si__proto__ est bien le même objet que le prototype de son constructeur.
Attention :Les remarques données plus haut sur les atteintes à la performance restent valables pour ces exemples. Ces exemples permettent uniquement d'illustrer le fonctionnement de__proto__, ils ne font pas office de recommandations.
// On déclare une fonction à utiliser comme constructeurfunction Employé() { /* on initialise l'instance */}// On crée une nouvelle instance d'Employévar fred = new Employé();// On teste l'équivalencefred.__proto__ === Employé.prototype; // trueÀ cet instant,fred hérite deEmployé. On peut toutefois changer ça en assignant un nouvel objet àfred.__proto__ :
// Assigner un nouvel objet à __proto__fred.__proto__ = Object.prototype;fred n'hérite plus deEmployé.prototype, mais deObject.prototype. Il perd donc les propriétés héritées deEmployé.prototype.
Cela n'est possible que pour les objetsextensibles. La propriété__proto__ d'un objet non-extensible ne peut pas être changée :
var obj = {};Object.preventExtensions(obj);obj.__proto__ = {}; // renvoie une exception TypeErrorOn notera que même la propriété__proto__ deObject.prototype peut être redéfinie tant que la chaîne de prototypes se termine parnull :
var b = {};Object.prototype.__proto__ = Object.create( null, //[[Prototype]] { salut: { value: function () { console.log("salut"); }, }, },);b.salut();Si la propriété__proto__ deObject.prototype ne permet pas d'aboutir ànull via la chaîne de prototypes, on a une chaîne cyclique et on doit avoir une exceptionTypeError "cyclic __proto__ value".
Spécifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-object.prototype.__proto__> |