Comment et pourquoi pourrais-je écrire une classe qui étend null?

La syntaxe de classe de JavaScript, ajoutée dans ES6, rend apparemment légal l’ extension de null :

 class foo extends null {} 

Quelques recherches sur Google révèlent qu’il a été suggéré sur ES que ces déclarations soient une erreur; cependant, d’autres commentateurs ont fait valoir qu’ils devaient restr légaux au motif que

quelqu’un pourrait vouloir créer une classe qui a un {__proto__: null}

et ce côté de l’argument a finalement prévalu.

Je ne peux pas donner beaucoup de sens à ce cas d’utilisation hypothétique. D’une part, alors que la déclaration d’une telle classe est légale, il semble que l’ instanciation d’ une classe déclarée de cette manière ne le soit pas. Essayer d’instancier la classe foo par dessus dans Node.js ou Chrome me donne l’erreur merveilleusement idiote

 TypeError: function is not a function 

tout en faisant la même chose dans Firefox me donne

 TypeError: function () { } is not a constructor 

Il n’est pas utile de définir un constructeur sur la classe, comme le montre l’exemple actuel de la fonctionnalité par MDN; si j’essaye d’instancier cette classe:

 class bar extends null { constructor(){} } 

alors Chrome / Node me dit:

 ReferenceError: this is not defined 

et Firefox me dit:

 ReferenceError: |this| used uninitialized in bar class constructor 

Qu’est-ce que toute cette folie? Pourquoi ces classes à extension nulle ne sont-elles pas instanciables? Et étant donné qu’ils ne sont pas instanciables, pourquoi la possibilité de les créer délibérément est-elle restée dans la spécification, et pourquoi un auteur de MDN a-t-il estimé qu’il était suffisamment intéressant pour documenter ? Quel est le cas d’utilisation possible pour cette fonctionnalité?

L’instanciation de telles classes est censée fonctionner; Chrome et Firefox ont juste des bogues. Voici Chrome, voici Firefox. Cela fonctionne très bien dans Safari (au moins sur master).

Il y avait un bogue dans la spécification qui les rendait impossible à instancier, mais cela a été corrigé pendant un certain temps. (Il y en a toujours un, mais ce n’est pas ce que vous voyez.)

Le cas d’utilisation est à peu près le même que celui de Object.create(null) . Parfois, vous voulez quelque chose qui n’hérite pas de Object.prototype .

Pour répondre à la deuxième partie:

Je ne peux pas donner beaucoup de sens à ce cas d’utilisation hypothétique.

De cette façon, votre object n’aura pas Object.prototype dans sa chaîne prototype.

 class Hash extends null {} var o = {}; var hash = new Hash; o["foo"] = 5; hash["foo"] = 5; // both are used as hash maps (or use `Map`). hash["toSsortingng"]; // undefined o["toSsortingng"]; // function 

Comme nous le soaps, la définition undefined n’est pas une fonction. Dans ce cas, nous pouvons créer des objects sans craindre un appel sur un champ qui ne devrait pas être là.

Ceci est un modèle commun à travers Object.create(null) et est commun dans beaucoup de bases de code, y compris les grandes comme NodeJS.