(function() {
let f = this ? class g { } : class h { };
return [ typeof f, typeof h ];
})();
Dans la question posée, nous avons une expression de fonction immédiatement invoquée (IIFE) en JavaScript. Cette fonction déclare une variable f en utilisant let, qui dépend de la valeur de this. Si this est vrai (ou un objet), f est une classe nommée g. Sinon, f est une classe nommée h.
La partie intéressante de ce code est la ligne suivante : return [ typeof f, typeof h ];.
Ici, nous nous attendons à ce que la variable f soit une function, car en JavaScript, les classes sont en réalité des fonctions spéciales. Donc, typeof f renverrait "function". Cependant, la variable h n'est pas définie dans la portée de la fonction et renvoie undefined lorsqu'on tente d'obtenir son type.
C'est pourquoi le bon choix de réponse à la question est ["function", "undefined"].
Il faut noter que la portée de la variable déclarée avec let est limitée à l'expression de bloc ({ }) ou à la déclaration d'une clause (for, if, etc.) dans laquelle elle est déclarée. Par conséquent, la variable h n'existe pas en dehors de la classe dans laquelle elle est définie et c'est pourquoi typeof h renvoie undefined.
De plus, il est également important de noter que this dans une fonction non méhodique fait référence à l'objet global (window dans un navigateur, global dans Node.js) sauf si la fonction est appelée avec new ou call/apply/bind, ou que le mode strict est activé (avec la directive "use strict";), où this serait undefined.
Considérons un exemple simple où nous modifions la valeur de this :
(function() {
let f = this ? class g { } : class h { };
return [ typeof f, typeof h ];
}).call({});
Ici, nous appelons la fonction avec un objet vide, donc this est vrai et f est class g { }. Encore une fois, typeof f renvoie "function" et typeof h renvoie "undefined".