Object.setPrototypeOf()
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é à effectuer Object.setPrototypeOf
, 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 utilisant Object.create()
La méthode Object.setPrototypeOf()
définit le prototype (autrement dit la propriété interne [[Prototype]]
) d'un objet donné avec un autre objet ou null
.
Syntaxe
Object.setPrototypeOf(obj, prototype);
Paramètres
Valeur de retour
L'objet sur lequel on a défini le prototype.
Description
Cette méthode renvoie une exception TypeError
si l'objet dont on souhaite modifier le [[Prototype]]
est non-extensible selon Object.isExtensible
. Cette méthode ne fait rien si le paramètre prototype n'est ni un objet ni null
(par exemple : un nombre, une chaîne, un booléen ou undefined
). Dans les autres cas, cette méthode substitue le [[Prototype]]
de obj
avec un nouvel objet.
Object.setPrototypeOf()
fait partie de la spécification ECMAScript 2015. L'utilisation de cette méthode est considérée comme la façon correcte pour modifier le prototype d'un objet (contrairement à la propriété Object.prototype.__proto__
plus controversée).
Exemples
var dict = Object.setPrototypeOf({}, null);
Prothèse d'émulation (polyfill)
En utilisant la propriété Object.prototype.__proto__
, on peut définir Object.setPrototypeOf
si elle n'est pas disponible :
// Cette prothèse ne fonctionne pas pour IE
Object.setPrototypeOf =
Object.setPrototypeOf ||
function (obj, proto) {
obj.__proto__ = proto;
return obj;
};
Ajouter une chaîne de prototypes à un objet
En combinant Object.getPrototypeOf()
et Object.prototype.__proto__
on peut ajouter une chaîne de prototypes au nouveau prototype d'un objet :
/**
*** Object.setPrototypeOf(@object, @prototype)
* Change le prototype d'une instance
*
**/
Object.setPrototypeOf = function (oInstance, oProto) {
oInstance.__proto__ = oProto;
return oInstance;
};
/**
*** Object.appendChain(@object, @prototype)
*
* Ajoute le premier prototype non-natif d'une chaîne au nouveau prototype.
* Renvoie @object (si c'est une valeur primitive, elle sera transformée
* en objet).
*
*** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
*** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
*
* Ajoute le premier prototype non-natif d'une chaîne à l'objet Function.prototype
* puis ajoute new Function(["@arg"(s)], "@function_body") à cette chaîne.
* Renvoie la fonction.
*
**/
Object.appendChain = function (oChain, oProto) {
if (arguments.length < 2) {
throw new TypeError("Object.appendChain - Pas suffisamment d'arguments");
}
if (typeof oProto !== "object" && typeof oProto !== "string") {
throw new TypeError(
"le deuxième argument de Object.appendChain doit être un objet ou une chaîne",
);
}
var oNewProto = oProto,
oReturn =
(o2nd =
oLast =
oChain instanceof this ? oChain : new oChain.constructor(oChain));
for (
var o1st = this.getPrototypeOf(o2nd);
o1st !== Object.prototype && o1st !== Function.prototype;
o1st = this.getPrototypeOf(o2nd)
) {
o2nd = o1st;
}
if (oProto.constructor === String) {
oNewProto = Function.prototype;
oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
this.setPrototypeOf(oReturn, oLast);
}
this.setPrototypeOf(o2nd, oNewProto);
return oReturn;
};
Utilisation
Ajouter une chaîne de prototypes à un prototype
function Mammifère() {
this.isMammifère = "oui";
}
function EspèceMammifère(sEspèceMammifère) {
this.espèce = sEspèceMammifère;
}
EspèceMammifère.prototype = new Mammifère();
EspèceMammifère.prototype.constructor = EspèceMammifère;
var oChat = new EspèceMammifère("Felis");
console.log(oChat.isMammifère); // "oui"
function Animal() {
this.respire = "oui";
}
Object.appendChain(oChat, new Animal());
console.log(oChat.respire); // "oui"
Deuxième exemple : Transformer une valeur primitive en une instance de son constructeur et ajouter sa chaîne à un prototype
function MySymbol() {
this.isSymbol = "yes";
}
var nPrime = 17;
console.log(typeof nPrime); // "number"
var oPrime = Object.appendChain(nPrime, new MySymbol());
console.log(oPrime); // "17"
console.log(oPrime.isSymbol); // "yes"
console.log(typeof oPrime); // "object"
Troisième exemple : Ajouter une chaîne de prototypes à l'objet Function.prototype object et ajouter une nouvelle fonction à cette chaîne
function Personne(sNom) {
this.identité = sNom;
}
var george = Object.appendChain(
new Person("George"),
'console.log("Salut !!");',
);
console.log(george.identité); // "George"
george(); // "Salut !!"
Spécifications
Specification |
---|
ECMAScript Language Specification # sec-object.setprototypeof |
Compatibilité des navigateurs
BCD tables only load in the browser