web-dev-qa-db-fra.com

'appelant' et 'arguments' sont des propriétés de fonction restreintes et ne sont pas accessibles dans ce contexte

J'essaie de créer une fonction de débogage simple qui montre simplement l'appelant d'une fonction, comme ceci:

function xe() {
  console.log(xe.caller().name)
}

Avec cela, je serais simplement en mesure d'ajouter xe() à une fonction et il enregistrera les appels à la fonction - juste un ajout court et simple pour aider au débogage. Débogage du sucre, pour ainsi dire.

Malheureusement, je reçois l'erreur de la ligne d'objet:

TypeError: 'appelant' et 'arguments' sont des propriétés de fonction restreintes et ne sont pas accessibles dans ce contexte.

J'utilise Babel/ES6, qui injecte "use strict" En haut de chaque module. Cela peut être la cause, mais la recherche a donné peu d'informations sur la raison pour laquelle l'erreur est déclenchée, et j'aimerais mieux la comprendre.

Si le mode strict est le problème, je préférerais ne pas désactiver le mode strict pour l'ensemble du projet - uniquement pour le module/la fonction.

20
Brian M. Hunt

C'est la cause. De MDN :

en mode strict, il n'est plus possible de "parcourir" la pile JavaScript via des extensions couramment implémentées d'ECMAScript. Dans le code normal avec ces extensions, quand une fonction fun est en cours d'appel, fun.caller est la fonction qui a récemment appelé fun, et fun.arguments sont les arguments pour cette invocation de fun. Les deux extensions sont problématiques pour JavaScript "sécurisé" car elles permettent au code "sécurisé" d'accéder aux fonctions "privilégiées" et à leurs arguments (potentiellement non sécurisés). Si fun est en mode strict, fun.caller et fun.arguments sont des propriétés non effaçables qui se déclenchent lorsqu'elles sont définies ou récupérées:

Si vous utilisez ES6, vous ne pouvez généralement pas désactiver le mode strict. C'est implicite pendant certaines conditions comme quand dans un module ES6.

Si vous ne faites que déboguer, je vous suggère d'utiliser un point d'arrêt dans un débogueur et de vérifier le cadre de la pile, mais je suis sûr que vous le savez déjà.

Si vous sortez simplement des informations de débogage, vous pouvez également le faire, je suppose qu'il suffit de lire la pile d'un objet Error:

console.log(new Error().stack);

Vous pouvez désactiver globalement (mais je me rends compte que ce n'est pas ce que vous voulez) use strict Avec babel En utilisant soit:

require("6to5").transform("code", { blacklist: ["useStrict"] });

ou

$ 6to5 --blacklist useStrict

Si vous devez le supprimer au niveau du module, je suppose que vous devrez le faire vous-même. Peut-être remplacer la chaîne de base?

De plus, comme cela a été souligné dans ES5. Il doit s'agir de xe.caller.name Et non de xe.caller().name ou vous invoquerez à nouveau la fonction.

22
Kit Sunde

Selon la documentation this . La propriété Function.caller() renvoie la fonction qui a appelé la fonction spécifiée. Vous obtiendrez simplement la fonction d'appel complet lorsque vous utilisez xe.caller. Encore une fois, vous exécutez la fonction d'appel. Ici, vous faites récursivité et c'est la raison pour laquelle cela n'est pas autorisé en mode strict.

Vous pouvez exécuter votre exemple de fonction dans la console du navigateur. tu auras Maximum call stack size exceeded Erreur.

1
Laxmikant Dange