19

編集: 明確にするために、問題の機能によって暗示されるさまざまな問題の定性的なメリットに関するアドバイスや意見を求めているわけではありません。また、実際の問題に対する信頼できる解決策を探しているわけでもありません。タイトルの質問に対する技術的で検証可能な回答を探しているだけです。質問に、非準拠ブラウザのリストを追加しました。

関数の.toStringメソッドを使用すると、通常、その関数のソース コードがレンダリングされます。問題は、この動作が指定されていないことです— 仕様は、関数に適用されたときの動作がどうあるべきかについての約束を控えています。Chrome のコンソールは、(関数以外のものを に渡すとFunction.toString.call) Function.prototype.toString が一般的ではないことを教えてくれます。

このブログ投稿は、複数行の文字列の読み取り可能な構文を生成する方法としてこれを使用できることを示唆しています (文字列をno-op 関数の本体に複数行のコメントとして格納することにより)。著者は、Node.js は制御された環境で実行されるため、この動作は信頼できるという条項を付けて、Node.jsアプリケーションを作成するコンテキストでこの使用法を提案しています。しかし、Javascript のネイティブ Web では、何でもやってきてそれを解釈することができ、不特定の動作に依存するべきではありません。

ただし実際には、コードをテストするために大きな複数行の文字列によって内容が決定される選択ボックスをレンダリングするフィドルを設定し、ワークステーションのすべてのブラウザー (Chrome 27、Firefox 21、Opera 12、Safari 5 、Internet Explorer 8) が意図したとおりに実行されます。

次のように動作しない現在の Javascript エンジンはどれですか?

とすれば:

function uncomment(fn){
  return fn.toString().split(/\/\*\n|\n\*\//g).slice(1,-1).join();
}

以下:

uncomment(function(){/*
erg
arg
*/});

出力する必要があります:

erg
arg

非準拠ブラウザのリスト:

  • Firefox 16
  • …</li>
4

2 に答える 2

6

現在、このように動作しない Javascript エンジンはどれですか?

「人気」を定義していないため、質問は明確に定義されていません。IE6は人気がありますか?IE5? IE4? ネットスケープナビゲーター? リンクス?質問に適切に答える唯一の方法は、サポートしたいブラウザーを列挙して確認することです。残念ながら、kangax のテーブルhttp://kangax.github.io/es5-compat-table/#は Function.prototype.toString をテストしていません

Chrome のコンソールは、(Function.toString.call 以外の関数を渡した場合)、Function.prototype.toString が一般的ではないことを教えてくれます。

仕様で義務付けられている

仕様は、関数に適用されたときの動作がどうあるべきかについてのコミットメントを控えています

必要な動作は ECMA-262 バージョン 1 で指定されています (1997 年以降、http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%201st%20edition,%20June%201997 .pdf ) あなたはそれを追跡する必要があります:

そのことから、関数はオブジェクトであると推測できます。

それでは、ToPrimitive とは何でしょう?

そのため、DefaultValue が何をするのかを知る必要があります

Function.prototype.toString が記述されている場所を見つける必要があります。

  • http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.2「関数の実装依存の表現が返されます。この表現には FunctionDeclaration の構文があります。特に、表現文字列内の空白、行末記号、およびセミコロンの使用と配置は、実装に依存します。」

そのため、適切な JavaScript 表現 (IL ゴブルデグックではない) が得られることが保証されますが、必ずしもコメントが含まれているとは限りません。たとえば、この手法は Firefox 16 で壊れます (ただし、それが最新かどうかを確認する必要があります)。

于 2013-06-07T16:49:03.787 に答える
1

そのため、Kangax は主題に戻り (Angular がクライアント側コードのコア機能にこのハックを使用しているという事実に興味をそそられました)、実践の分析を書き上げ、関数逆コンパイルの状態のテスト テーブルを作成しました。 Javascript で

要点は次のとおりです。

  • この手法は、ユーザー定義の関数宣言に対してのみリモートで信頼できます。
  • 一部の古いモバイル ブラウザは、パフォーマンス上の理由から、依然として機能コードを折りたたんでいます。
  • 他の古いブラウザーでは、Closure Compiler から得られるような最適化されたコードが表示されます。
  • さらに、コメントを削除して空白を変更する人もいます。
  • Internet Explorer では、関数の周りにコメントや空白が追加されることがあります。
  • AngularJS チームは、この手法は十分に堅牢であり、明示的な警告なしにライブラリに含めることができると考えているようです。次に、コードをトークン化し (!)、再評価します (!!)。

私の目的では、これにより、関数に大文字の名前があるかどうかを次のように解析することで検出するなど、比較的要求の少ないことを実行できるとかなり確信で​​きます。

/function\s*[A-Z]/.test( fn )
于 2014-10-20T10:21:55.483 に答える