Un fait "amusant" JS __proto__
![](https://post.nghiatu.com/assets/images/m/max/724/1*8ptwktzg8YTy1a3KW-j9EA.jpeg)
Si vous me suivez depuis assez longtemps, vous savez déjà à quel point __proto__
j'ai toujours été contre et pourtant, depuis qu'il est passé au standard ECMAScript il y a longtemps, il y a encore de rares occasions où je trouve au moins son utilisation pour marquer un objet acceptable :
const factory = (fields, {prototype} = Object) => ({
__proto__: prototype,
...fields
});
// mimic an <a /> reference
factory({href: '/'}, HTMLAnchorElement);
![](https://post.nghiatu.com/assets/images/m/max/724/1*ubXaTL0j8uwNL8T8yp1NTQ.png)
Mis à part les performances, et veuillez noter que je ne suggère pas du __proto__
tout l'utilisation de dans la nature, ce message existe pour d'autres raisons.
Objet.prototype.__proto__
Je suis à peu près sûr que tout le monde sait ce que fait l'accesseur __proto__ , alors j'aimerais vous proposer un défi… et oui, tout cela est valide JS :
class Test {}
const __proto__ = Test.prototype;
// what do these operations return?
({__proto__} instanceof Test);
({__proto__: __proto__} instanceof Test);
({"__proto__": __proto__} instanceof Test);
({["__proto__"]: __proto__} instanceof Test);
// what do these operations return?
({__proto__}.__proto__ === Test.prototype);
({__proto__: __proto__}.__proto__ === Test.prototype);
({"__proto__": __proto__}.__proto__ === Test.prototype);
({["__proto__"]: __proto__}.__proto__ === Test.prototype);
Si vous n'avez pas exécuté vous-même ces extraits pour connaître la réponse, je peux vous aider ! Dans le premier défi, la sortie sera false
, true
, true
et false
encore une fois, et la raison en est que les deux {__proto__}
et {["__proto__"]}
sont définis comme propriété propre , tandis que l'affectation via la syntaxe, sans utiliser de fonctionnalités de syntaxe spéciales, même avec des guillemets autour, passe en fait par l' Object.prototype.__proto__
accesseur.
D'un autre côté, dans le deuxième défi (tous true
), peu importe si nous accédons __proto__
directement ou en tant que ["__proto__"]
, de sorte qu'il n'y a fondamentalement aucune symétrie dans la façon dont nous pouvons déclencher le __proto__
setter, de la façon dont nous pouvons déclencher le __proto__
getter une fois c'est soit une propriété propre, soit une porte d'héritage magique.
… et pas seulement __proto__
Je ne me suis pas vérifié moi-même, mais je pense que chaque __xxx__
accesseur spécial hérité souffre de la même __proto__
malédiction, alors faites attention de mélanger la dernière syntaxe JS cool pour attribuer des propriétés avec votre intention et vos attentes réelles, car les choses pourraient facilement devenir folles si vous essayez de soyez intelligent dans l' attribution de ces propriétés .
Et c'est tout !
La seule chose à retenir de ce message est probablement résumée ainsi :
- n'utilisez pas de parties du langage héritées mais encore fonctionnelles, si vous souhaitez éviter les surprises aujourd'hui ou demain sur la façon dont elles se comportent avec la nouvelle syntaxe
- préférez explicite (et malheureusement plus lent)
Object.setPrototypeOf
chaque fois que la définition manuelle du prototype d'un objet est strictement requise, mais utilisez des classes dans tous les autres cas chaque fois que cela est possible - effacez de votre mémoire ce message ou réduisez-le en une courte phrase comme : " Je ne devrais jamais utiliser
__proto__
dans mon code " et avancez en apprenant de nouvelles choses fantaisistes qui ne gâchent pas votre cerveau ou vos sentiments