この記事のタイトルですが、この記事を書いた人も読んだ人もバカではないと思います。しかし、時々、トピックによって自分がバカにされたように感じられることがあります。少なくとも私にとっては、JavaScript エンジンもそのようなトピックの 1 つです。
Web アプリケーションのコードを記述するのは、まるで魔法のように感じられることがあります。これは、一連の文字を記述するだけで、その効果がブラウザーで確認できるからです。しかし、魔法の背後にあるテクノロジーを理解すれば、プログラミング スキルをさらに向上させることができます。少なくとも、JavaScript を使用した Web アプリやモバイル アプリの舞台裏で何が起こっているのかを説明しようとするときに、自分が馬鹿であると感じることは少なくなります。
何年も前、私が大学院講師だったとき、学部生に教えられるほど特に難しいフランス語の文法事項をまだ習得していないと教授に不満を言いました。その時彼女が言ったことを覚えています。「何かを学ぶ唯一の方法は、それを教えることです
」NativeScript が JavaScript エンジンを通じてバックグラウンドでどのように動作し、実行時にネイティブ API を接続して呼び出しているかをエンジニアに説明してみてください。このような複雑なタスクに直面すると、雑草の中に埋もれてしまいがちです。実際、JavaScript 開発者なら誰でも、私たちが毎日使用しているテクノロジーの基礎となるエンジンに興味があるはずです。ここで、JavaScript エンジンが実際に何を行うのか、異なるプラットフォームで異なるエンジンが使用される理由、それらが長年にわたってどのように進化してきたのか、そして開発者としてなぜ注意すべきなのかを詳しく見てみましょう。
まず、専門用語をいくつか説明します
「JavaScript エンジン」は、仮想マシンと呼ばれることがよくあります。 「仮想マシン」とは、特定のコンピュータ システムのソフトウェア駆動のエミュレータを指します。仮想マシンには多くの種類があり、実際の物理マシンをどの程度正確にシミュレートまたは置き換えるかに応じて分類されます。
たとえば、「システム仮想マシン」は、オペレーティング システムを実行できる完全なエミュレーション プラットフォームを提供します。 Mac ユーザーにはおなじみの Parallels は、Mac 上で Windows システムを実行できるようにする仮想マシンです。
一方、「プロセス仮想マシン」はすべての機能を備えているわけではなく、プログラムやプロセスを実行できます。 Wine は、Linux マシン上で Windows アプリケーションを実行できるようにするプロセス仮想マシンですが、Linux で完全な Windows オペレーティング システムを提供するわけではありません。
JavaScript 仮想マシンは、JavaScript コードを解釈して実行するように特別に設計されたプロセス仮想マシンです。
注: ブラウザーでページ レイアウトをレイアウトするレイアウト エンジンと、コードを解釈して実行する基盤となる JavaScript エンジンを区別することが重要です。良い説明はここにあります。
それでは、JavaScript エンジンとは何ですか?また、何をするのでしょうか?
JavaScript エンジンの基本的な仕事は、開発者が作成した JavaScript コードを、ブラウザーで解釈したり、アプリケーションに埋め込んだりできる効率的で最適化されたコードに変換することです。実際、JavaScriptCore は自らを「最適化された仮想マシン」と呼んでいます。
より正確に言うと、各 JavaScript エンジンは ECMAScript のバージョンを実装しており、JavaScript はそのフォークです。 ECMAScript が進化し続けるにつれて、JavaScript エンジンも改良され続けています。これほど多くの異なるエンジンがある理由は、それぞれが異なる Web ブラウザー、ヘッドレス ブラウザー、または Node.js などのランタイム環境で実行されるように設計されているためです。
Web ブラウザーについてはよく知っているかもしれませんが、ヘッドレス ブラウザーとは何ですか?グラフィカル ユーザー インターフェイスを持たない Web ブラウザです。これらは、Web 製品のテストを自動化するときに役立ちます。良い例は PhantomJS です。では、Node.js は JavaScript エンジンとどのような関係があるのでしょうか? Node.js は、サーバー側で JavaScript を使用できるようにする非同期のイベント駆動型フレームワークです。これらは JavaScript を利用するツールであるため、JavaScript エンジンも利用します。
上記の仮想マシンの定義によれば、JavaScript エンジンは JavaScript コードを読み取ってコンパイルすることだけが目的であるため、プロセス仮想マシンと呼ばれることは容易に理解できます。だからといって、単純なエンジンというわけではありません。たとえば、JavaScriptCore には、JavaScript コードを分析、解釈、最適化、ガベージ コレクションできる 6 つの「ビルディング ブロック」があります。
どのように機能しますか?
もちろん、これはエンジンによって異なります。私たちの注目を集めた 2 つの主要なエンジンは、WebKit の JavaScriptCore と Google の V8 エンジンで、どちらも NativeScript を利用しています。 2 つのエンジンは異なる方法でコードを処理します。
JavaScriptCore は、スクリプトを解釈して最適化するための一連の手順を実行します:
字句解析を実行します。これは、ソース コードを明確な意味を持つ一連の記号または文字列に分解します。
これらのシンボルは、構文アナライザーを使用して分析され、構文ツリーが構築されます。
次に、4 つの JIT (Just-In-Time) プロセスが参加し始め、パーサーによって生成されたバイトコードを分析して実行します。
何?簡単に言うと、JavaScript エンジンはソース コードをロードし、それを文字列に分割し (トークン化とも呼ばれます)、これらの文字列をコンパイラが理解できるバイトコードに変換してから、これらのバイトコードを実行します。
Google の V8 エンジンは C で書かれており、JavaScript ソース コードをコンパイルして実行し、メモリ割り当てとガベージ コレクションを処理することもできます。これは、ソース コードをマシン コードに直接コンパイルできる 2 つのコンパイラーで構成されるように設計されています:
フルコード生成: 最適化されていないコードを出力する高速コンパイラー
クランクシャフト: 効率的で最適化されたコードを出力する低速コンパイラー
Crankshaft が最適化が必要なコードが Full-codegen によって生成された最適化されていないコードであると判断した場合、Full-codegen と呼ばれる「クランクシャフト化」プロセスが置き換えられます。
コンパイル プロセス中にマシン コードが生成されると、エンジンは ECMA 標準で指定されたすべてのデータ型、演算子、オブジェクト、関数、または実行時に使用する必要があるものをブラウザに公開します。ネイティブスクリプト。
どのような JavaScript エンジンがありますか?
クライアント側のコードを解釈、分析、実行するために使用できる JavaScript エンジンは、目まぐるしいほど数多くあります。ブラウザの各バージョンがリリースされると、JavaScript コード実行テクノロジの変化に対応するために、その JavaScript エンジンが変更または最適化される場合があります。
これらのブラウザ エンジンの名前に完全に混乱する前に、これらのエンジンとそれに基づくブラウザには多くのマーケティングが行われていることを覚えておいてください。 JavaScript のコンパイルに関するこの非常に有益な分析の中で、著者は皮肉を込めて次のように指摘しています。 、スマートなマーケティング、したがって SquirrelFish、Nitro、SFX という名前が付けられました...」
これらのエンジンの命名と名前変更に対するマーケティングの影響を念頭に置きながら、JavaScript エンジンの歴史の中でいくつかの重要な出来事に注目することは有益です。わかりやすい表を作りました:
ブラウザ、ヘッドレスブラウザ、またはランタイム | JavaScript エンジン |
---|---|
モジラ | スパイダーモンキー |
クロム | V8 |
サファリ | JavaScriptコア |
IE と Edge | チャクラ |
PhantomJS | JavaScriptコア |
HTMLユニット | サイ |
TrifleJS | V8 |
Node.js | V8 |
Io.js* | V8 |
*JavaScriptCore 改寫為 SquirrelFish,升級版本為 QuirrelFish Extreme,也稱為 Nitro。然而,構成 Webkit 實作基礎的 JavaScript 引擎就是 JavaScriptCore(例如 Safari)。
**iOS 開發者應該要知道行動裝置的 Safari 使用 Nitro,但是 UIWebView 不包含 JIT 編譯,所以體驗會比較慢一些。然而開發人員可以在 iOS8 中使用包含 Nitro 的 WKWebView,使用體驗 明顯 變快。混合行動應用程式的開發人員應該能鬆口氣了。
*最終 io.js 從 Node.js 分離開的原因之一就是為了支援 V8 版本的引擎。這仍然是一個挑戰,正如 這裡 所講述的。
我們為什麼要關注?
JavaScript 引擎的程式碼解析和執行過程的目標就是在最短時間內編譯出最優化的程式碼。
最重要的是,這些引擎的演進與我們對發展 web 和 行動平台的持續探究息息相關,讓它們盡可能具有高性能,是相輔相成的。為了追蹤這種演進,你可以看到各種各樣的引擎在基準圖中是如何表現的,就好像 arewefastyet.com 總結的。例如,比較 Chrome 在搭載 V8 引擎與 non-Crankshafted 引擎時的表現就很有趣。
任何一個 web 開發者都要意識到,我們努力編寫、調試和維護的程式碼在不同瀏覽器中執行效果必然有所差異。為什麼某段程式碼在一個瀏覽器上工作得很慢,但在另一個上卻快得多?
同樣地,行動開發者,尤其是使用webview 顯示頁面內容的混合行動應用程式開發者,或是那些使用像NativeScript 這種執行時間環境的開發者,想知道是什麼引擎在解釋執行他們的JavaScript 程式碼。行動 web 開發者應該注意到那些小型設備上的瀏覽器所具備的各種限制和可能性。作為一個想持續發展的 web、行動或應用程式開發人員,時刻關注 JavaScript 引擎的變化會帶給你超值回報。
總結:
js 中的基本資料型態 undefined null boolean number string
js 中的一種複雜資料型態 object 它是所有物件的基礎型別
js 和其他語言一樣擁有9種基本的控制語句
js 中的函數無需指定回傳值,實際上未指定傳回值的函數傳回的是undefined
js 中的參數可以隨意的傳遞 注意arguments[] 陣列 它可以幫助你
js 中的函數是不能重載的,但你可以模仿。