検索
ホームページウェブフロントエンドjsチュートリアルJavaScriptで関数のシリアル化を行う方法 SpiderMonkey_基礎知識

Javascript では関数を簡単にシリアル化 (文字列化)、つまり関数のソース コードを取得できますが、実際にはこの操作の内部実装 (エンジン実装) は思っているほど単純ではありません。 SpiderMonkey では 2 つが使用されます。関数シリアル化テクノロジには 3 つあります。1 つは逆コンパイラを使用して、関数のコンパイルされたバイトコードをソース コード文字列に逆コンパイルするもので、もう 1 つは関数をバイトコードにコンパイルする前に関数のソース コードを圧縮するものです。

関数をシリアル化する方法
SpiderMonkey には、関数をシリアル化できるメソッドまたは関数が 3 つあります。 Function.prototype.toSource、unval。toString メソッドのみが標準です。つまり、すべてのエンジンに共通です。ただし、ES 標準 (ES5 15.3.4.2) には、Function.prototype.toString メソッドに関する説明がいくつかあります。 ) つまり、基本的に標準はなく、それをどのように実装するかはエンジンが決定します。

関数のシリアル化の主な役割は次のとおりです。シリアル化ソース コードによって生成された関数を使用して、この関数を再定義します。

コードをコピーします コードは次のとおりです:
function a() {
...
alert("a")
...
}

a() //"a" は可能性があります実行中にポップアップします

a = eval("(" a.toString().replace('alert("a")', 'alert("b")') ")")

a() // 実行時に "b" がポップアップ表示される場合があります


あなたは次のように考えているかもしれません。確かに、自分の Web サイトの場合は、js ファイルを完全に制御できます。このパッチ適用方法で関数を変更する必要はなく、直接変更するだけです。しかし、ソース ファイルが制御下にない場合は、たとえば、greasemonkey スクリプトが一般的に使用されます。Web サイトの機能を無効にしたり、変更したりする必要がある場合があります。Firefox 自体の特定の機能を変更する必要がある場合もあります。 Firefox は JS で書かれていると言っています)。これは私が書いた例です
Firefox スクリプトの例
:
コードをコピーします コードは次のとおりです。location == "chrome:/ /browser/content/browser.xul" && eval("gURLBar.handleCommand=" gURLBar.handleCommand.toString().replace( /^s*(load. );/gm, "/^javascript:/.test(url )||(content.location=='about:blank'||content.location=='about:newtab')? $1:gBrowser.loadOneTab(url,{postData:postData,inBackground:false,allowThirdPartyFixup: true}) ;"))
このコードの機能は次のとおりです: アドレス バーで Enter キーを押すと、Firefox が開きます。これを実現するには、toString メソッドを使用して gURLBar を読み取り、正規表現に置き換えて eval に渡して関数を再定義します。

それを直接定義しないのはなぜですか。つまり、関数を直接書き換えてください:

gURLBar.handleCommand = function(){...//元の関数を小さな場所で変更します}
これができない理由は、互換性を考慮する必要があるためです。そうであれば、この関数のソースコードはできるだけ変更しない方がよいでしょう。 書いてあるように、Firefox の gURLBar.handleCommand のソースコードが変更されると、このスクリプトになります。たとえば、Firefox3 と Firefox4 の両方にこの機能がありますが、機能の内容は大きく異なります。ただし、一部のキーワードを正規表現を使用して置き換える場合、このキーワードが変更されない限り、問題は発生します。


Decompile bytecode
SpiderMonkey では、関数はバイトコード (バイトコード) に解析された後にコンパイルされます。つまり、元の関数のソース コードが保存されます。 SpiderMonkey にはデコンパイラがあり、その主な機能は関数のバイトコードを関数ソース コードの形式に逆コンパイルすることです。
Firefox16 以前のバージョンでは、SpiderMonkey はこの方法を使用します。これらのバージョンの Firefox を使用している場合は、次のコードを試してください:


alert(function () {
"String";
//Comment
return 1 2 3
}.toString())
返される文字列は
です
関数 () {
戻り値
}


出力は他のブラウザとは完全に異なります:

1. 意味のないプリミティブ値リテラルはコンパイル中に削除されます。この例では、それは「文字列」です。

「問題ないようです。いずれにせよ、これらの値は関数の動作にとって意味がありません。待って、何か忘れていませんか?」と思われるかもしれません。これは strict を意味します。パターン文字列「use strict」はどうすればよいですか?

Firefox 3.6 などの strict モードをサポートしていないバージョンでは、この「use strict」は他の文字列と変わらないため削除されます。 SpiderMonkey が strict モードを実装した後は、コンパイル時に "use strict" という文字列も無視されますが、この関数が strict モードであるかどうかは、関数本体の先頭にあると判断されます。 「use strict」を 1 行に追加します。対応するエンジンのソース コードは次のとおりです。


コードをコピーします。 コードは次のとおりです。
DecompileBody(JSPrinter *jp, JSScript *script, jsbytecode *pc)
{
/* 必要に応じて、厳密モード コード ディレクティブを出力します。 . */
if (script->strictModeCode && !jp->strict) {
if (jp->fun && (jp->gt;fun->flags & JSFUN_EXPR_CLOSURE)) {
/*
* 厳密な関数式の構文はありません。
* 少なくともヒントを与えてください。
*/
js_printf(jp, "t/* use strict */ n");
} else {
js_printf(jp, "t"use strict";n");
}
jp->strict = true;

jsbytecode *end = script-> ;code script->length;
return DecompileCode(jp, script, pc, end - pc, 0);



2コンパイル中のコメントも削除されます

これはあまり影響がないようですが、一部の人々は関数のコメントを使用して複数行の文字列を実装します。 Firefox 17 より前のバージョン。


コードをコピー
コードは次のとおりです。 function hereDoc(f ) { return f.toString( ).replace(/^. s/,"").replace(/. $/,"");
} var string = hereDoc(function () {/*

あなた

*/});
console.log(string)



あなた

3. 元の値 リテラル操作はコンパイル時に実行されます

これは、「高性能 JavaScript」で説明されている

です。 逆コンパイルの欠点

新しいテクノロジー (厳密モードなど) の出現により、また他の関連バグを変更する場合、逆コンパイラのこの部分の実装を変更する必要があることがよくあります。変更により新しいバグが発生する可能性があります。私はこれを個人的に経験しました。おそらく Firefox 10 の頃でした。具体的な問題ははっきりとは覚えていませんが、おそらく次のようなものでした。 >

コードをコピー

コードは次のとおりです:
逆コンパイル時に括弧(a b) は省略されています。加算結合は左から右に進むため、問題ありません。しかし、私が遭遇したバグは次のとおりです。




コードをコピー


コードは次のとおりです:
これは機能しません。たとえば、a=1、b=2、c="3" の場合、a b c は "33" に等しくなります。 (b c) は "123 " に等しい。

逆コンパイラに関して、Mozilla エンジニアの Luke Wagner は、逆コンパイラがいくつかの新機能の実装を大きく妨げており、しばしばいくつかのバグを抱えていると指摘した。まだまだ続きますが、私も昨年、逆コンパイラーによる多大な影響を感じました。また、テストのカバレッジも低く、些細でない変更は必ずファズバグを生み出します。この影響を早く取り除くほど、より早く利益を得ることができます。特に、新しい言語機能のために大規模なフロントエンド/バイトコードのハッキングを行った後よりも、今がそれを削除するより良い時期だと思います。

Brendan Eich 氏は、逆コンパイラーには多くの欠点があるとも言いました。

私は逆コンパイラには愛がありません。17 年間ハッキングされ続けています。ストレージ関数のソース コード
Firefox17 以降、SpiderMonkey は 2 番目の実装方法に変更されました。他のブラウザもこの方法で実装する必要があります。空白文字やコメントなどを含めてソースコードと完全に一致しています。この場合、ほとんどの問題は解消されるはずですが、

については別の質問があるようです。例:


(function A() {
"use strict";
alert("A");
}) ""


もちろん、返されるソース コードには "use strict" も含まれている必要があります。すべてのブラウザで true これは実現されます:


関数A() {
"厳密な使用";
alert("A");


次の場合はどうなるでしょう:


コードをコピー コードは次のとおりです: (function A() {
"use strict";
return function B() {
alert( "B")
}
})() ""


内部関数 B も厳密モードである必要があります。 B? を出力する関数のソースコードに strict を追加します。試してみてください:
上記の通り、Firefox17 以前と Firefox4 以降のバージョンでは、現在の関数が含まれているかどうかを判断して、「use strict」を出力するかどうかを決定します。関数 B は関数 A の厳密モードを継承します。したがって、「厳密な使用」が行われます。

同時に、SpiderMonkey は逆コンパイルされたソース コードをフォーマットするため、厳密にインデントされます。前のソース コードにインデントがまったくない場合でもソース コード


function B() {
" use strict";
コードをコピー


コードは次のとおりです:

function B() {
"use strict";
alert(" B") } SpiderMonkey の最新バージョンの jsfun.cpp ソース コードには対応するコメントがあります// 関数の上位関数に「use strict」がある場合、この関数は上位関数の strict モードを継承します。
// また、「use strict」を挿入します。この内部関数の関数本体
// これにより、この関数の toString がメソッドの戻り値を再評価するときに、
// 再生成された関数が元の関数と同じセマンティクスを持つことが保証されます。


違いは、他のブラウザには「use strict」がないことです:



コードをコピーします


コードは次のとおりです。


function B() {
alert("B")
}
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptはCで書かれていますか?証拠を調べるJavaScriptはCで書かれていますか?証拠を調べるApr 25, 2025 am 12:15 AM

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター