2017-09-13 2 views
2

JavaScriptでは、ローカル変数は私が認識しているオブジェクトには存在しません。それは最後のオプションeval('x')は名前でこれらの変数を参照することが可能であることを示し、名前パターンによるローカルjavascript変数の検索

function foo() { 
    const x = 2; 

    self.x; // undefined 
    this.x; // undefined 
    window.x; // undefined 
    x; // 2, obviously 
    eval('x'); // 2 
} 

です。これはオブジェクトの上に住んでいた場合、私はmyObject[Object.keys(myObject).find((key) => key.startsWith('foobar_'))]のようなものを使用することになり

function foo() { 
    // Code not under my direct control 
    function foobar_abc() {} 
    function other_functions() {} 

    // Code under my control 
    const matchingFunction = // find the function with name matching 'foobar_*' 
} 

:私はこれを拡張し、名前パターンを使用して変数にアクセスしていますよ。グローバルスコープの場合、myObjectwindowとなり、すべて動作します。

evalが名前で変数にアクセスできるという事実は、値がどこかで利用可能であることを意味します。この変数を見つける方法はありますか?あるいは、私が直接コントロールしていない(潜在的に非常に複雑な)コードを書き直すテクニックに頼らなければならないのですか?

私は近代的なブラウザをターゲットにしています。この使用例では、evalまたは同様のハックの解決策を使用しても構いません。ユーザー提供のコードの実行が目的であるため、任意のコードは既に実行されています。

+0

普通のブラウザの場合は、おそらく 'window [X]'が必要でしょう。 'this.hasOwnProperty(X)'はどうでしょうか? 'this'オブジェクトはあなたに現在のスコープを与えます。基本的には 'for(これで名前をつけてください){...}'を実行できるはずです – Dekel

+0

これはhttps://stackoverflow.com/questions/2051678/getting-all-variables-in-scopeの複製であるようです –

+0

@Dekelこれはローカルスコープの変数なので、 'window'でも' this'でもありません。それはどこかのオブジェクトに存在するかもしれませんが、まだ私はそれについて聞いていません! – Dave

答えて

1

もう1つの方法は、コード解析を使用して、javascript AST(抽象構文ツリー)ライブラリを使用して関数名を推測することです。

https://www.npmjs.com/package/esprima

だからあなたはそれが動作するはず示唆しているドキュメントで、私はこれを試していない自分自身を

import esprima from 'esprima' 

const userCodeStructure = esprima.parseScript(userProvidedJavascriptString); 

const allTopLevelFunctionDeclarations = userCodeStructure.body.filter(declaration => declaration.type === "FunctionDeclaration"); 

const allTopLevelFunctionNames = allTopLevelFunctionDeclarations.map(d => d.id); 

を行うことができます(または何か:「esprima」パッケージには、おそらく見て良い場所になりますそれのように):変数名に頼る

http://esprima.readthedocs.io/en/latest/

+0

似たような回答が重複していることに気付かず、私はリンクしました、申し訳ありません。私はこれが良いアプローチだと思う。 –

+0

これはおそらく、リンクされた質問の外観から利用可能な最も正しい答えです。 – Dave

+0

@Dave:http://astexplorer.net/の恥知らずなプラグ); –

0

ここで役立つ可能性のあるアプローチは、関数ではなくグローバルスコープで評価することです。関数はローカルスコープではなくウィンドウオブジェクトに配置される可能性があります。

これを行う最も簡単な方法は、ドキュメントに新しいタグを書き込み、ユーザー提供のコードを注入することです。

0

は間違ったアプローチです。

evalは悪です。 CSPでは利用できない場合があります。コードがブラウザで実行されるはずであることを考慮すると、最も大きな問題は、の変数に予想される名前がないことです。彼らはa,b, ...

名前を維持するために、それらはオブジェクトプロパティでなければならず、オブジェクト上で利用できるようにする必要があります。

または私は技術に頼らなければなりません(潜在的に非常に複雑な)コード

これはリファクタリングであり、それは匂いと大きな問題を作成し、不正なコードを避けるために行われるべきものだを再書き込み。

+0

私はあなたが私のコントロール下にないコードのソースを誤解していると思います。実行時に**ユーザから提供されます**。私が手作業で修正できるコードはありません。それを実行する前にアルゴリズム的に固定する必要があります。同じ理由で、それは決して縮小されません。 – Dave

+1

@DaveこれはXYの問題かもしれません。答えは質問と同じくらい良いです。このコードがどこから由来しているのか、それが何であるのか、正確に何をしているのかについて詳しく説明してください。 *私の直接の管理下にないコード*と私の管理下の*コードは十分な説明ではありません。言われたように、これは縮小されたコードでは機能しません。 – estus

+0

私は今までの説明は圧倒的なものではなく、十分詳細であると思います。または、少なくとも、リンクされた重複していると投票された答えは、私が知りたいと思ったものをカバーしています。あなたが本当に詳細を知りたいのであれば、私はオンラインで「キング・オブ・ザ・ヒル」ゲームを走らせるためのエンジンに取り組んでいます.PPCGサイトから古い課題を実装しています。これは特に:https://codegolf.stackexchange.com/questions/67560/king-of-the-hill-spacewarには、パターンに従って命名された関数が必要です。複数の回答で命名に間違いがあったため、名前の自動検出が望ましい – Dave

関連する問題