I.背景
長年、私はさまざまな場面でUltraEditをエディターとして使用してきました。 主な理由の1つは、ギガバイトファイルをメモリにロードせずに高速で処理できることです。 JavaScriptでのプログラミングにも非常に便利ですが、重要な欠点が1つだけあります。自動補完は、言語の開発に遅れをとることに加えて、キーワードとグローバル変数のかなり貧弱で厳密に定義されたリストに基づいています。 どういうわけか、Node.jsとWeb API(ブラウザ)のコンテキストで入力できるすべての既製のプロパティとメソッドの完全なリストでこのリストを補充できるかどうか疑問に思いました。 そのようなリストはどこで入手できますか? 私には次のオプションがありました。
グローバルライブラリのように、一般的な使用のために誰かがコンパイルして更新した既製のリストですが、より完全です。
ドキュメント(ECMAScript仕様、MDN、Node.jsサイトなど)を手動またはプログラムで解析します。
- メタプログラミングによるリストの取得。
私の質問に対する主な答えは、編集者を変えて苦労しないという提案でした。 しかし、大きなファイル用の便利なエディターはそれほど多くなく、私のミニマリズムによってさまざまなニーズに合わせていくつかのエディターを使用することは難しく、プログラミングは私の主な仕事ではなかったので、私はあきらめませんでした。 結局、私にとっては実用的な作業だけでなく、根本的な関心もありました。それは、どうしてそんなに単純なニーズに思えるかですが、簡単な解決策はありません。
既製のリストは見つからず、ドキュメントの解析は長くて信頼性の低い方法なので、3番目の方法を試してみることにしました。
II。 コード
いくつかのヒントを使用して、さまざまなコンテキストでさまざまな言語の命名法を表示する小さなスクリプトをいくつかの方法で作成しました。
それは私が得たものです。
スクリプトは、Node.jsまたはブラウザで(コンソールまたはページに貼り付けて)実行できます。 最初の場合、結果はファイルに表示され、2番目の場合-現在のドキュメントに追加されたテキストフィールドに表示されます(コンソールでabout:blank
を開くことができます)。
コードについてコメントしようとします。
1.最初に、メインコンテナ変数を作成します。 最初の2つでは、命名法を蓄積します: nomenclatureTerms
、すべてのトークンの単純なリストがnomenclatureChains
同じトークンですが、ルートオブジェクトから始まる完全なチェーンで格納されます。 globs
には、ボールをほどいてツリーを構築するための開始点、 globs
グローバル(ルート)オブジェクトを格納します。 循環参照による無限再帰を回避するために、すべての処理済みオブジェクトを後続の検証のために、 processedObjects
追加します。
2.第2段階では、 globs
ます。
最初に、スクリプトは実行されるコンテキストを決定しようとします。 ブラウザであれば、 window
オブジェクトで十分です。
Node.jsの場合、事態はもう少し複雑です。 最初に、 require
と同様に2つの主要なグローバルオブジェクトを追加します。そうしないrequire
、この関数にアクセスできません。 次に、すべての標準ライブラリのオブジェクトを追加します。主要な部分は、Node.js開発者の1人が推奨するドキュメント化されていないリストrequire('repl')._builtinLibs
ています。 結論として、いくつかの__dirname
内変数( __dirname
および__filename
)はグローバルオブジェクトにバインドされていないため、すぐに命名コンテナーに追加します。
3.主な作業は次のとおりです。再帰関数processKeys
を使用しprocessKeys
すべてのグローバルオブジェクトと、プロパティに格納されているすべてのオブジェクトを可能な限り最後まで移動します。 次に、コンテキストに応じて結果を出力し、アイテムのサイズのコンソールへの最終出力で終了します(スクリプトはかなりの時間実行されるため、この出力は完了信号として機能します-Chromeはこの信号の後でもページを更新するために追加の時間が必要になる場合があります)
4.プロセスprocessKeys
は、プロセスのメインエンジンです。
最初に、ルートオブジェクトを処理しているかどうかを確認します。 もしそうなら、私たちはすぐに彼の名前を命名法に入れました。 オブジェクトがオブジェクトの子プロパティにある場合、このエントリは再帰の前の段階ですでに発生しているため、スキップします。
次に、処理対象のオブジェクトのリストにオブジェクトを入力して、悪の無限に陥らないようにします。
その後、オブジェクトのすべてのプロパティをバイパスし始めます。 これを行うには、オブジェクトの通常の文字列キーとSymbolタイプのキーの両方をリストするだけなので、 Reflect.ownKeys()
メソッドを使用します。 各プロパティをnomenclatureTerms
( Set
タイプは繰り返しを自動的に破棄します)、親オブジェクトの名前と現在のプロパティからチェーンを形成し、それをnomenclatureChains
入力します。 同じチェーンが次の再帰呼び出しのオブジェクトの名前になるので、さらに進化すると常に成長します(すべての場合にソートを統一するために角括弧付きの表記を選択しました:通常の識別子にドットを使用し、複雑な文字列に角括弧を使用すると、出力の順序が崩れますリスト; JSON.stringify
再保険に使用されます-プロパティ名の一部として可能な引用符をエスケープします)。 データベースに入力される前のSymbol型のキーは文字列にキャストされます(残念ながら、これにより、プロパティチェーン内のそのようなキーを持つデータベース要素は、REPL Node.jsやブラウザコンソールなどの直接的な解釈に適さなくなります-その前に、そのようなキーを再度入力してキャストする必要があります記号、文字列表現から余分な部分を削除します)。
次のステップでは、プロパティに保存されているものを確認します。オブジェクトの場合、このオブジェクトがまだ処理済みのリストにない場合、新しい再帰呼び出しを行います。 instanceof Object
はObject.prototype
とObject.create(null)
作成されたオブジェクトに対してfalse
を返すため、客観性テストは2つありinstanceof Object
。
このような広範なプロパティの通過は、多くの場合エラーを引き起こすため、プロセスが中断しないようにハンドラーを追加する必要があります(エラーメッセージの出力は好奇心のために残されています)。 また、私たちの要望に加えて、コンソールには、 deprecated
ステータスを受け取ったプロパティを要求しようとする試みに関するいくつかの警告が表示deprecated
ます。
5. output
関数は、実行コンテキストに応じて結果を出力します。 まず、より馴染みのある語彙順でソートされたリストを形成します(ただし、FirefoxではcaseFirst
パラメーターは機能しません)。 次に、実行コンテキストを確認します。ブラウザーでは、現在のページに埋め込まれた2つのテキストフィールドにリストが表示されます(エディターを使用してリストを保存できるファイルの名前がリストの上部に追加されます)。 Node.jsは、現在のディレクトリに2つのファイルを作成します。
スクリプトの関数の名前がブラウザーリストに追加され、さまざまな環境変数がNode.jsリストに追加されることに注意してください。 このリストには、内部使用、配列インデックスなどの文書化されていないさまざまなプロパティも含まれています。 一方、多くの命名文字列要素(たとえば、イベント名や標準の関数文字列パラメーター)はリストに含まれていません。
III。 結果
Node.jsの最新ベータバージョンと2つのブラウザのナイトリービルドでスクリプトを実行した後、次のリストを受け取りました(データは2016年10月18日に更新されました)。
Node.js 7.0.0-test201610107f7d1d385d
用語:1 822
チェーン:7 394
Google Chrome Canary 56.0.2891.0
用語:3 352
チェーン:15 091
Mozilla Firefox Nightly 52.0a1(2016-10-17)
用語:5 082
チェーン:16125
おそらく、プログラムの結果にはさまざまな用途があるかもしれません。 たとえば、異なるブラウザーまたは同じブラウザーの異なるバージョンの命名法を比較します(テスト中、近隣の日の夜間のアセンブリは、数十の位置で異なる結果をもたらすことがあることに気付きました-何かが導入され、何かが歴史に残る)。 プロセスを自動化すると、たとえば、多くのバージョンでNode.js API履歴を作成できます。 また、プロパティの深さ、識別子の長さ、作成の原則など、さまざまな言語統計を収集できます。
確かに、コードは速度、使いやすさ、結果の完全性または読みやすさのために最適化できます。 また、言語の微妙さや使用状況の無知のために、いくつかの愚かな間違いを犯す可能性があります。 修正と追加に感謝します。 ご清聴ありがとうございました。
PS良い例: http : //electron.atom.io/blog/2016/09/27/api-docs-json-schema