Obtenez toutes les valeurs de la fermeture dans node.js ou V8

Par exemple, si nous supposons le code suivant:

var f = function() { return 'hello world' }; var x = 10; var y = 314; var g = function() { var buf = [], xx = x; while (xx--) buf.append(f() + ' '); return buf.join(''); } 

Je peux obtenir le "code" actuel comme une chaîne de g avec g.toString() . Cependant, cela ne provoque pas (obviamente) f et x membres de la fermeture de g (désolé si je n'utilise pas ces termes correctement).

Existe-t-il un moyen d'interroger une fonction pour ce qu'elle contient? Idéalement, je pourrais obtenir un objet comme:

 { 'f' : f, 'x': x } // note that `y` is not here 

Si je dois tomber dans C ++ pour des interactions spéciales avec V8, ça va bien, bien que, dans certains cas, il soit préférable de créer un JavaScript pur.


Je sais que c'est une question étrange, mais j'ai une raison légitime de vouloir cela!

J'ai trouvé cette discussion sur les implémentations de fermeture V8 éclairantes. Cela ressemble à l'objet C ++ que vous recherchez est un contexte .

Vous voulez avoir une liste de toutes les variables qui s'utilisent dans cette fonction, n'est-ce pas? Le moyen rapide et sale serait probablement d'utiliser quelque chose comme l'analyseur et les choses AST de UglifyJS pour parcourir la fonction afin que vous puissiez alors obtenir une liste de toutes les variables, etc.

Modifier:

Une telle méthode n'existe pas. Si vous êtes déconseillé de le faire en JavaScript, votre meilleur pari serait d'écrire un analyseur qui déterminerait quelles variables une fonction se referme.

Si vous écrivez une telle méthode, partagez 🙂

Publication originale:

Dans votre exemple, la fermeture g a accès à f et y . x est déclaré comme une variable locale donc x NE FAIT PAS 10. Il n'y a pas une méthode spéciale qui vous dira les variables auxquelles une fonction se termine.

Si g était une méthode d'un objet, vous pouvez utiliser la fonction hasOwnProperty de l'objet pour déterminer les propriétés disponibles pour l'objet. AFAIK c'est la seule chose qui se rapproche de déterminer les variables auxquelles une fonction a accès en JavaScript.

Il n'y a pas de fermeture dans le code que vous avez posté. Vous pouvez obtenir la valeur de n'importe quelle variable que vous voulez à n'importe quel point et ce sera ce que votre fonction g voit. Tout simplement parce que vous appelez une fonction à partir d'une autre fonction ne fait pas de fermeture. Pour qu'il y ait une fermeture, f devrait être une variable de la portée de la fonction g et ce n'est pas le cas. Ces deux fonctions sont dans la même portée que votre x et y, vraisemblablement le global. Si vous deviez dire envelopper ce chiot entier dans une fonction plus grande, ils seraient toujours dans la même portée, mais si vous deviez retourner f et g d'une fonction englobant, alors vous envisageriez une fermeture où x et y le ferait Être privé de la fonction de retour, partagé avec f et g. Ensuite, vous auriez besoin d'une forme de fonction getter qui devrait également être renvoyée et pourrait communiquer en définissant la valeur d'une variable d'observation en un seul lien dans la chaîne de portée.

Dans l'état actuel des choses, avec le code présenté, x est x et y c'est pourquoi, vérifiez-les quand vous voulez et c'est leur valeur, ce qui est aussi ce que f et G verraient.

Ricky Gee

Comme l'a dit Ricky Gee, il n'y a pas de problème ici, car les variables sont toutes globales, afin que vous puissiez les rejoindre à travers l'objet global. Cependant, si nous supposons que le code n'était pas global, alors non, vous ne pouvez pas extraire une référence aux variables f, x et y (ni leurs valeurs) de la fermeture de g.

Vous ne pouvez pas le faire en JavaScript, et vous ne pouvez pas le faire via l'API V8. Évidemment, les données sont quelque part, mais V8 n'essaie même pas de rendre disponibles ses structures de données internes.