| JavaScript | |
|---|---|
JavaScriptソースコードのスクリーンショット | |
| パラダイム | マルチパラダイム:イベント駆動型、関数型、命令型、手続き型、オブジェクト指向 |
| 家族 | ECMAスクリプト |
| デザイン: | 最初はNetscapeのBrendan Eich氏、その後他のメンバーがECMAScript標準に貢献した。 |
| 初登場 | 1995年12月4日[ 1 ] (1995年12月4日) |
| 安定版リリース | |
| プレビューリリース | |
| タイピングの規律 | ダイナミック、弱い、アヒル |
| メモリ管理 | ガベージコレクション |
| 範囲 | 語彙 |
| ファイル名拡張子 | .js• .mjs• .cjs[ 4 ] |
| Webサイト | ecma-international |
| 主要な実装 | |
| V8、JavaScriptCore、SpiderMonkey、Chakra(非推奨) | |
| 影響を受けた | |
| Java、[ 5 ] [ 6 ] Scheme、[ 6 ] Self、[ 7 ] AWK、[ 8 ] HyperTalk [ 9 ] | |
| 影響を受けた | |
| ActionScript、ArkTS、AssemblyScript、CoffeeScript、Dart、Haxe、JS++、Opa、TypeScript | |
| |
JavaScript(JS)[ a ]は、 HTMLやCSSと並んでWebの中核技術であり、プログラミング言語です。 1995年にブレンダン・アイクによって開発されました。[ 6 ] 2025年現在、ウェブサイトの圧倒的多数(98.9%)がクライアント側のウェブページ動作にJavaScriptを使用しています。[ 10 ]
ウェブブラウザには、クライアントコードを実行する専用のJavaScriptエンジンが搭載されています。これらのエンジンは、一部のサーバーや様々なアプリでも利用されています。ブラウザ以外での利用で最も普及しているランタイムシステムはNode.jsです。[ 11 ]
JavaScriptは、ECMAScript標準に準拠した、高水準で、多くの場合ジャストインタイムコンパイル(JIT)方式の言語です。[ 12 ]動的型付け、プロトタイプベースのオブジェクト指向、そして第一級関数を備えています。また、マルチパラダイムに対応し、イベント駆動型、関数型、命令型といったプログラミングスタイルをサポートしています。テキスト、日付、正規表現、標準データ構造、そしてドキュメントオブジェクトモデル(DOM) を扱うためのアプリケーションプログラミングインターフェース(API)を備えています。
ECMAScript標準には、ネットワーク、ストレージ、グラフィックス機能といった入出力(I/O)は含まれていません。実際には、Webブラウザやその他のランタイムシステムがI/O用のJavaScript APIを提供しています。
Javaと JavaScript は名前と構文が似ていますが、2 つの言語は別個のものであり、設計は大きく異なります。
グラフィカルユーザーインターフェースを備えた最初の人気ウェブブラウザであるMosaicは1993年にリリースされました。Mosaicの主任開発者はその後Netscape社を設立し、同社は1994年にさらに洗練されたブラウザであるNetscape Navigatorをリリースしました。これはすぐに最も使用されるブラウザとなりました。[ 13 ]
Webの黎明期、Webページは静的なものであり、ブラウザにページが読み込まれた後の動的な動作は不可能でした。当時活況を呈していたWeb開発シーンでは、この制約を解消したいという要望が高まり、1995年、NetscapeはNavigatorにプログラミング言語を追加することを決定しました。同社はこれを実現するために、2つの方法を採用しました。1つはSun Microsystemsと提携してJava言語を組み込み、もう1つはBrendan Eichを雇用してScheme言語を組み込むというものでした。[ 6 ]
その目標は「大衆のための言語」[ 14 ] 、 「プログラマー以外の人が動的でインタラクティブなWebサイトを作成できるようにする」ことだった。[ 15 ] Netscapeの経営陣はすぐに、Javaに似た構文を持ち、Schemeや他の既存のスクリプト言語に似ていない新しい言語をアイヒが考案するのが最善の選択肢であると判断した。[ 5 ] [ 6 ]新しい言語とそのインタープリタ実装は、1995年9月にNavigatorベータ版の一部として最初に出荷されたときにはLiveScriptと呼ばれていたが、12月の正式リリースではJavaScriptに名前が変更された。[ 6 ] [ 1 ] [ 16 ] [ 17 ]
JavaScriptという名称の選択は、Javaと直接関連しているという印象を与え、混乱を招きました。当時、ドットコム・ブームが始まり、Javaは人気の高い新しい言語であったため、アイヒ氏はJavaScriptという名称はNetscapeのマーケティング戦略だと考えました。[ 14 ]
マイクロソフトは1995年にInternet Explorerを発表し、Netscapeとのブラウザ戦争を引き起こしました。JavaScriptに関しては、マイクロソフトはJScriptと呼ばれる独自のインタープリタを開発しました。[ 18 ]
マイクロソフトは1996年にJScriptを初めてリリースし、同時にCSSとHTML拡張機能も初期サポートしました。これらの実装は、 Netscape Navigatorの対応するものとは大きく異なっていました。[ 19 ] [ 20 ]これらの違いにより、開発者はウェブサイトを両方のブラウザで適切に動作させることが困難になり、「Netscapeで最適表示」および「Internet Explorerで最適表示」というロゴが長年にわたり広く使用されました。[ 19 ] [ 21 ]
ブレンダン・アイクは後にこの時期についてこう述べている。「まだ一種の脇役言語です。遅い、あるいは煩わしいと考えられています。ポップアップや、古いブラウザの下部にある古いステータスバーにスクロールするメッセージが表示されるのです。」[ 14 ]
1996年11月、NetscapeはJavaScriptをEcma Internationalに提出しました。これは、すべてのブラウザベンダーが準拠できる標準仕様の出発点となるものでした。これにより、1997年6月に最初のECMAScript言語仕様が正式にリリースされました。
標準化プロセスは数年間継続され、1998年6月にECMAScript 2、1999年12月にECMAScript 3がリリースされました。ECMAScript 4の作業は2000年に始まりました。[ 18 ]
しかし、言語の完全標準化に向けた努力は、Microsoftがブラウザ市場でますます支配的な地位を築いたことにより、損なわれました。2000年代初頭には、Internet Explorerの市場シェアは95%に達しました。[ 22 ]これは、 JScriptがWeb上の クライアントサイドスクリプティングの事実上の標準となったことを意味します。
マイクロソフトは当初、標準化プロセスに参加し、JScript言語にいくつかの提案を実装しましたが、最終的にはECMAの活動への協力を中止しました。こうしてECMAScript 4は廃止されました。
2000年代初頭のInternet Explorerの優位性により、クライアントサイドスクリプティングは停滞していました。しかし、2004年にNetscapeの後継であるMozillaがFirefoxブラウザをリリースしたことで、状況は変化し始めました。Firefoxは多くの人々に好評を博し、Internet Explorerから大きな市場シェアを奪いました。[ 23 ]
2005年、MozillaはECMA Internationalに加盟し、ECMAScript for XML (E4X) 標準の策定作業を開始しました。これにより、Mozillaは、ECMAScript 4の草案をベースとしたActionScript 3言語にE4Xを実装していたMacromedia (後にAdobe Systemsに買収)と共同で作業を進めることになりました。目標は、ActionScript 3を新しいECMAScript 4として標準化することでした。この目標達成のため、Adobe SystemsはTamarin実装をオープンソースプロジェクトとして公開しました。しかし、TamarinとActionScript 3は既存のクライアントサイドスクリプティングとは大きく異なっており、Microsoftの協力なしにはECMAScript 4は実現しませんでした。
一方、ECMAの活動とは無関係のオープンソースコミュニティでは、非常に重要な進展が見られました。2005年、ジェシー・ジェームズ・ギャレットはホワイトペーパーを発表し、その中で「Ajax」という用語を考案し、JavaScriptを基盤とした一連の技術について説明しました。この技術は、バックグラウンドでデータを読み込み、ページ全体の再読み込みを必要とせずにWebアプリケーションを作成するためのものです。これがJavaScriptのルネサンス期のきっかけとなり、オープンソースライブラリとそれらを中心に形成されたコミュニティがその先駆けとなりました。jQuery 、Prototype、Dojo Toolkit、MooToolsなど、多くの新しいライブラリが作成されました。
Googleは2008年に競合他社よりも高速なV8 JavaScriptエンジンを搭載したChromeブラウザを発表しました。 [ 24 ] [ 25 ]重要な革新はジャストインタイムコンパイル(JIT)でした。[ 26 ]そのため、他のブラウザベンダーはJITのためにエンジンを全面的に改良する必要がありました。[ 27 ]
2008年7月、これらの異なる関係者はオスロで会議を開きました。その結果、2009年初頭に、関連するすべての作業を統合し、言語を前進させることで最終的に合意に達しました。その結果、2009年12月にECMAScript 5標準がリリースされました。
この言語に関する野心的な作業は数年にわたって続けられ、 2015年にECMAScript 6が公開され、広範な追加と改良が正式に発表されました。[ 28 ]
2009年にライアン・ダールがNode.jsを開発したことで、ウェブブラウザ以外でのJavaScriptの利用が大幅に増加しました。Node.jsはV8エンジン、イベントループ、I/O APIを組み合わせ、スタンドアロンのJavaScriptランタイムシステムを提供しています。[ 29 ] [ 30 ] 2018年時点で、Node.jsは数百万人の開発者に利用されており、[ 31 ] npmは世界で最も多くのモジュールを持つパッケージマネージャーとなっています。 [ 32 ]
ECMAScriptのドラフト仕様は現在GitHubで公開されており[ 33 ]、定期的に毎年スナップショットが公開されています。[ 33 ]言語の改訂案は包括的な提案プロセスを通じて審査されます。[ 34 ] [ 35 ]現在、開発者はエディション番号ではなく、今後の機能の状況を個別に確認しています。[ 33 ]
現在のJavaScriptエコシステムには、多くのライブラリやフレームワーク、確立されたプログラミング手法、そしてウェブブラウザ以外でのJavaScriptの大幅な使用があります。[ 17 ]さらに、シングルページアプリケーションやその他のJavaScriptを多用するウェブサイトの増加に伴い、開発プロセスを支援するためにいくつかのトランスパイラが作成されています。[ 36 ]
「JavaScript」は米国オラクル社の商標です。 [ 37 ] [ 38 ]この商標は1997年5月6日にサン・マイクロシステムズ社に最初に発行され、2009年にオラクル社がサンを買収した際にオラクル社に譲渡されました。[ 39 ] [ 40 ]
2024年9月にはライアン・ダールが先頭に立ってオラクルにJavaScriptの商標を解放するよう求める書簡が回覧された。 [ 41 ] JavaScriptのオリジナル作者であるブレンダン・アイクもこの取り組みを支持した14,000人以上の署名者の一人でした。
JavaScriptはWebのクライアント側スクリプト言語として主流で、Webサイトの99%がこの目的で使用しています。[ 10 ]スクリプトはHTML文書に埋め込まれたり、HTML文書から取り込まれたりして、 DOMと対話します。
すべての主要なWeb ブラウザには、ユーザーのデバイス上で コードを実行するJavaScript エンジンが組み込まれています。
ウェブサイトの80%以上が、クライアントサイドスクリプトの一部としてサードパーティのJavaScriptライブラリまたはウェブフレームワークを使用しています。 [ 42 ]
jQueryは圧倒的に最も多く使用されています。[ 42 ]その他の注目すべきものとしては、Angular、Bootstrap、Lodash、Modernizr、React、Underscore、Vueなどがあります。[ 42 ] jQueryとBootstrapのように、複数のオプションを組み合わせて使用することもできます。[ 43 ]
しかし、「Vanilla JS」という用語は、ライブラリやフレームワークを一切使用せず、代わりに標準的なJavaScript機能に完全に依存しているウェブサイトのために造られました。[ 44 ]
JavaScript の用途は、Web ブラウザの枠を超えて拡大しています。JavaScriptエンジンは現在、サーバーサイドのWeb サイト展開や非ブラウザアプリケーションなど、さまざまなソフトウェア システムに組み込まれています。
サーバーサイドJavaScriptの利用を促進する最初の試みはNetscape Enterprise ServerとMicrosoftのInternet Information Servicesであったが[ 45 ] [ 46 ]、これらはニッチな市場であった。[ 47 ]サーバーサイドの利用は、 Node.jsやその他のアプローチの登場により、2000年代後半にようやく増加し始めた。[ 47 ]
Electron、Cordova、React Nativeなどのアプリケーションフレームワークは、JavaScriptで実装された動作を持つ多くのアプリケーションの作成に使用されてきました。ブラウザ以外のアプリケーションとしては、PDFドキュメントのスクリプト作成をサポートするAdobe Acrobat [ 48 ]や、 JavaScriptで記述されたGNOME Shell拡張機能[ 49 ]などがあります。
Oracleは、 Java開発キット(JDK) APIライブラリの一部として、JavaScriptインタープリタのNashornをJDKバージョン8のコマンドラインインタープリタのjjsとともに提供していました。これはJDK 15で削除されました。代替としてOracleは、 OpenJDKでも使用できるGraalJSを提供しました 。これにより、JavaScriptコードでJavaオブジェクトを作成および参照し、Javaで記述されたアプリケーションにJavaScriptのランタイムスクリプトを追加できます。[ 50 ] [ 51 ] [ 52 ] [ 53 ]
JavaScriptは、通常Node.jsを活用して、いくつかの組み込みシステムで使用されています。 [ 54 ] [ 55 ] [ 56 ]
JavaScript 用の最初のエンジンはソースコードの単なるインタープリターでしたが、最近の関連するエンジンはすべて、パフォーマンスを向上させるためにジャストインタイムコンパイルを使用しています。 [ 57 ] JavaScript エンジンは通常、ウェブブラウザーベンダーによって開発され、すべての主要なブラウザーに 1 つずつあります。ブラウザーでは、JavaScript エンジンは、ドキュメントオブジェクトモデルとWeb IDLバインディングを介してレンダリングエンジンと連携して動作します。[ 58 ]ただし、JavaScript エンジンの使用はブラウザーに限定されません。たとえば、V8 エンジンは、 Node.jsランタイムシステムのコアコンポーネントです。[ 59 ]これらは、仕様の正式名称にちなんで、 ECMAScriptエンジンとも呼ばれます。WebAssemblyの登場により、一部のエンジンでは、このコードを通常の JavaScript コードと同じサンドボックスで実行できるようになりました。[ 60 ] [ 59 ]
スクリプトがより広範な環境とやり取りできるようにするには、 JavaScriptエンジンをランタイムシステム( Webブラウザやスタンドアロンシステムなど)に組み込む必要があります。ランタイムシステムには、ネットワーク、ストレージ、グラフィックスといった入出力操作に必要なAPIが含まれており、スクリプトをインポートする機能も提供しています。
JavaScriptはシングルスレッド言語です。ランタイムはキューからのメッセージを1つずつ処理し、各メッセージに関連付けられた関数を呼び出して、関数の引数とローカル変数を含むコールスタックフレームを作成します。コールスタックは関数の必要に応じて縮小または拡大します。関数の完了時にコールスタックが空になると、JavaScriptはキュー内の次のメッセージに進みます。これはイベントループと呼ばれ、「完了まで実行する」と表現されます。これは、各メッセージが完全に処理されてから次のメッセージが検討されるためです。しかし、JavaScriptの並行性モデルでは、イベントループは非ブロッキングとして記述されます。つまり、プログラムI/Oはイベントとコールバック関数を用いて実行されます。つまり、例えばJavaScriptは、データベースクエリが情報を返すのを待っている間にマウスクリックを処理できます。[ 61 ]
注目すべきスタンドアロン ランタイムとしては、Node.js、Deno、Bunなどがあります。
以下の機能は、明示的に指定されない限り、すべてのECMAScript準拠実装に共通です。引用されている予約語の数はキーワードを含めて50~60個で、実装によって異なります。
JavaScriptはC言語の構造化プログラミング構文の多くをサポートしています(例:文、ループ、文、ループなど)。部分的な例外として、スコープがあります。JavaScriptは元々、関数スコープ( )のみをサポートしていましたが、ECMAScript 2015ではキーワード と によってブロックスコープが追加されました。C言語と同様に、JavaScriptは式と文を区別します。C言語との構文上の違いの一つは、セミコロンの自動挿入です。これにより、文の末尾となるセミコロンを省略できます。[ 62 ]ifwhileswitchdo whilevarletconst
JavaScriptは弱い型付けであり、使用される操作に応じて特定の型が暗黙的にキャストされることを意味します。[ 63 ]
+演算子は、両方のオペランドが数値でない限り、両方のオペランドを文字列に変換します。これは、加算演算子が連結演算子としても機能するためです。-演算子は常に両方のオペランドを数値に変換します+, -) はどちらも常にオペランドを数値に変換します。ただし、は常に( binary64 )+に変換されますが、 は( integer )を維持します[ 64 ]Number-BigInt値は次のように文字列に変換される。[ 63 ]
,)で結合されます。[object Object]ある文字列に変換されます。Object値を数値に変換するには、まず文字列にキャストし、次に文字列を数値にキャストします。これらの処理は、プロトタイプにそれぞれ文字列キャストと数値キャストの関数を定義toStringすることで変更できます。 valueOf
JavaScriptは、これらの変換の実装方法について、ルールの複雑さが矛盾と誤解される可能性があるとして批判を受けています。[ 65 ] [ 63 ]たとえば、文字列に数値を加算する場合、連結を実行する前に数値を文字列に変換しますが、文字列から数値を減算する場合、減算を実行する前に文字列を数値に変換します。
| 左オペランド | オペレーター | 右オペランド | 結果 |
|---|---|---|---|
[](空の配列) | + | [](空の配列) | ""(空の文字列) |
[](空の配列) | + | {}(空のオブジェクト) | "[object Object]"(弦) |
false(ブール値) | + | [](空の配列) | "false"(弦) |
"123"(弦) | + | 1(番号) | "1231"(弦) |
"123"(弦) | - | 1(番号) | 122(番号) |
"123"(弦) | - | "abc"(弦) | NaN(番号) |
よく言及されるのは、{} + []結果として0(数値) が生成されるという点です。これは誤解を招きます。(数値){}は空のオブジェクトではなく空のコードブロックとして解釈され、空の配列は残りの単項演算子によって数値に変換されます+。式が括弧 ( - ({} + [])- ) で囲まれている場合、中括弧は空のオブジェクトとして解釈され、式の結果は"[object Object]"期待どおりになります。[ 63 ]
JavaScriptは他のほとんどのスクリプト言語と同様に動的型付けされます。型は式ではなく値に関連付けられます。例えば、最初は数値にバインドされていた変数は、文字列に再割り当てされることがあります。[ 66 ] JavaScriptは、ダックタイピングを含む、オブジェクトの型をテストする様々な方法をサポートしています。[ 67 ]
JavaScript には、eval実行時に文字列として提供されたステートメントを実行できる関数が含まれています。
JavaScript におけるプロトタイプ継承は、Douglas Crockfordによって次のように説明されています。
プロトタイプオブジェクトを作成し、それから…新しいインスタンスを作成します。JavaScriptではオブジェクトは可変なので、新しいインスタンスに新しいフィールドやメソッドを追加して拡張することができます。そして、それらはさらに新しいオブジェクトのプロトタイプとして機能します。多数の類似したオブジェクトを作成するためにクラスは必要ありません…オブジェクトはオブジェクトを継承します。これ以上にオブジェクト指向的なことがあるでしょうか?[ 68 ]
JavaScriptでは、オブジェクトは連想配列であり、プロトタイプ(下記参照)が追加されています。各キーはオブジェクトのプロパティ名を表します。プロパティ名を指定する構文には、ドット記法(obj.x = 10)と角括弧記法(obj["x"] = 10)の2種類があります。プロパティは実行時に追加、再バインド、または削除できます。オブジェクトのほとんどのプロパティ(およびオブジェクトのプロトタイプ継承チェーンに属するすべてのプロパティ)は、ループを使用して列挙できますfor...in。
JavaScriptは、他の多くのオブジェクト指向言語が継承にクラスを使用するのに対し、プロトタイプを使用します。 [ 69 ]しかし、プロトタイプシステムを使用して、クラスベースの機能のほとんどをシミュレートすることは依然として可能です。[ 70 ]さらに、ECMAScriptバージョン6 (2015年6月リリース)では、 class、extends、superというキーワードが導入されました。これらは、より従来的なインターフェースを使用して、基盤となるプロトタイプ継承システムを抽象化する構文糖として機能します。コンストラクタはconstructorというメソッドを指定して宣言され、Javaと同様に、すべてのクラスは自動的に基本クラスObjectのサブクラスになります。
クラスPerson {コンストラクター( name ) { this . name = name ; } }クラスStudent はPersonを拡張します{コンストラクター( name 、id ) { super ( name ); this . id = id ; } }const bob = new Student ( "Robert " , 12345 ); console . log ( bob . name ); // Robert基盤となるオブジェクト機構は依然としてプロトタイプに基づいていますが、新しい構文は他のオブジェクト指向言語に似ています。プライベート変数は、フィールド名の前に番号記号(#)を付けて宣言されます。ポリモーフィズムは直接サポートされていませんが、引数の数と型に応じて異なる関数を手動で呼び出すことでエミュレートできます。[ 71 ]
関数は、その典型的な役割に加えて、オブジェクトコンストラクタとしても機能します。関数呼び出しの前にnewを付けると、プロトタイプのインスタンスが作成され、コンストラクタからプロパティとメソッド(Objectプロトタイプのプロパティを含む)が継承されます。[ 72 ] ECMAScript 5 ではObject.createメソッドが提供されており、プロトタイプから自動的に継承することなく、明示的にインスタンスを作成できますObject(古い環境ではプロトタイプを に割り当てることができますnull)。[ 73 ]コンストラクタのprototypeプロパティは、新しいオブジェクトの内部プロトタイプに使用されるオブジェクトを決定します。コンストラクタとして使用される関数のプロトタイプを変更することで、新しいメソッドを追加できます。
// このコードは、前のスニペットfunction Person ( name ) { this . name = name ; }と完全に同等です。関数Student ( name , id ) { Person . call ( this , name ); this . id = id ; }var bob = new Student ( "Robert " , 12345 ); console . log ( bob . name ); // RobertJavaScript の組み込みクラス( や など)にArrayもObject、変更可能なプロトタイプがあります。しかし、組み込みオブジェクトを変更することは一般的に悪い習慣とされています。サードパーティのコードがこれらのオブジェクトのメソッドやプロパティを使用または継承する可能性があり、プロトタイプが変更されることを想定していない可能性があるためです。[ 74 ]
多くのオブジェクト指向言語とは異なり、JavaScriptでは関数定義とメソッド定義の区別はありません。むしろ、関数呼び出し時に区別が行われます。関数がオブジェクトのメソッドとして呼び出されると、その関数のローカルなthisキーワードは、その呼び出しの間、そのオブジェクトにバインドされます。
JavaScript関数は第一級関数であり、関数はオブジェクトとみなされます。[ 75 ]そのため、関数には.call()やなどのプロパティやメソッドがある場合があります.bind()。[ 76 ]
ネストされた関数とは、別の関数内で定義された関数です。外側の関数が呼び出されるたびに作成されます。
さらに、各ネストされた関数はレキシカルクロージャを形成します。つまり、外側の関数のレキシカルスコープ(定数、ローカル変数、引数値を含む)は、外側の関数の実行が終了した後でも、内側の関数オブジェクトの内部状態の一部になります。[ 77 ]
JavaScript は匿名関数もサポートしています。
JavaScript は暗黙的および明示的な委任をサポートします。
JavaScriptは、Traits [ 79 ] [ 80 ]やMixin [ 81 ]といった、 Role [ 78 ]パターンの様々な関数ベースの実装をネイティブにサポートしています。このような関数は、その本体内でキーワードにバインドされた少なくとも1つのメソッドによって追加の動作を定義します。Roleは、プロトタイプチェーンで共有されない追加の動作を必要とするオブジェクト に対して、明示的に委譲する必要があります。thisfunctioncallapply
JavaScriptにおける明示的な関数ベースの委譲は合成をカバーしますが、暗黙的な委譲はプロトタイプチェーンを辿るたびに既に行われています。例えば、オブジェクトと関連している可能性があるものの、直接所有されていないメソッドを見つける場合などです。メソッドが見つかると、そのオブジェクトのコンテキスト内で呼び出されます。このように、 JavaScriptにおける継承は、コンストラクタ関数のプロトタイププロパティに結び付けられた委譲の自動化によってカバーされています。
JavaScript はゼロインデックス言語です。
関数には、無制限の数のパラメータを渡すことができます。関数は、仮パラメータとローカルargumentsオブジェクトの両方を介して、これらのパラメータにアクセスできます。また、メソッドを使用することで、可変長引数関数を作成することもできますbind。
多くのスクリプト言語と同様に、配列とオブジェクト(他の言語では連想配列)はそれぞれ簡潔なショートカット構文で作成できます。実際、これらのリテラルはJSONデータ形式の基礎となっています。
JavaScriptはテキストの検索と操作のための正規表現をサポートしています。 [ 72 ]:139
組み込みの Promise オブジェクトは、Promise を処理し、非同期アクションの最終結果にハンドラーを関連付ける機能を提供します。JavaScript にはコンビネータメソッドが用意されており、開発者は複数の JavaScript Promise を組み合わせ、さまざまなシナリオに基づいた操作を実行できます。導入されているメソッドは、Promise.race、Promise.all、Promise.allSettled、Promise.any です。
async/await を使用すると、非同期の非ブロッキング関数を通常の同期関数と同様の構造にすることができます。非同期の非ブロッキングコードは、最小限のオーバーヘッドで、従来の同期のブロッキングコードと同様の構造で記述できます。
歴史的に、一部のJavaScript エンジンは次のような非標準機能をサポートしていました。
function(args) expr; この実験的な構文は矢印関数より前からあった)JavaScriptの変数はvar、[ 83 ] let[ 84 ]またはconst[ 85 ]キーワードを使用して定義できます。キーワードを使用せずに定義された変数は、グローバルスコープで定義されます。
アロー関数は、第6版(ECMAScript 2015 )で初めて導入されました。JavaScriptで関数を記述する際の構文を短縮します。アロー関数は匿名関数であるため、括弧で囲んで即時実行しない限り、作成後に呼び出すには変数への参照が必要です。
以下は JavaScript 構文の例です。
// 関数スコープの変数 `x` を宣言し、暗黙的に特別な値 `undefined` を割り当てます。値のない変数は自動的にundefined に設定されます。// var は一般的に悪い習慣と考えられており、let と const が推奨されます。var x ;// 変数は次のように手動で `undefined` に設定できます。let x2 = undefined ;// ブロックスコープの変数 `y` を宣言し、暗黙的に`undefined` に設定します。`let` キーワードは ECMAScript 2015 で導入されました。let y ;// ブロックスコープで再代入不可能な変数 `z` を宣言し、文字列リテラルに設定します。`const` キーワードも ECMAScript 2015 で導入され、明示的に代入する必要があります。// キーワード `const` は定数を意味するため、値が `constant` であるため、変数を再割り当てすることはできません。const z = "この値は再割り当てできません!" ;// グローバルスコープの変数を宣言し、3 を割り当てます。これは通常、悪い習慣と考えられており、厳密モードがオンの場合は機能しません。t = 3 ;// `myNumber` という名前の変数を宣言し、数値リテラル (値`2`) を割り当てます。let myNumber = 2 ;// `myNumber` を再割り当てし、文字列リテラル (値 `"foo"`) に設定します。// JavaScript は動的型付け言語なので、これは有効です。myNumber = " foo" ;上記の例のコメントはすべて 2 つのスラッシュで始まっていることに注意してください。
さらに多くの例については、Wikibooks の JavaScript 構文例のページをご覧ください。
JavaScriptとDOMは、悪意のある作成者がWeb経由でクライアントコンピュータで実行するスクリプトを配信する危険性をはらんでいます。ブラウザの開発者は、2つの制限を設けることでこのリスクを最小限に抑えています。まず、スクリプトはサンドボックス内で実行されます。サンドボックス内では、ファイル作成などの汎用プログラミングタスクではなく、Web関連のアクションのみを実行できます。次に、スクリプトは同一オリジンポリシーによって制約されます。つまり、あるウェブサイトのスクリプトは、別のサイトに送信されたユーザー名、パスワード、Cookieなどの情報にアクセスできません。JavaScript関連のセキュリティバグの多くは、同一オリジンポリシーまたはサンドボックスのいずれかの違反によるものです。
一般的なJavaScriptのサブセットであるADsafe、Secure ECMAScript(SES)は、特に第三者が作成したコード(広告など)に対してより高いレベルのセキュリティを提供します。[ 86 ] [ 87 ] Closure Toolkitは、サードパーティのJavaScriptとHTMLを安全に埋め込み、分離するための別のプロジェクトです。[ 88 ]
コンテンツ セキュリティ ポリシーは、Web ページ上で信頼できるコードのみが実行されるようにするための主な方法です。
JavaScript関連の一般的なセキュリティ問題の一つに、クロスサイトスクリプティング(XSS)があります。これは、同一オリジンポリシー違反です。XSS脆弱性は、攻撃者がオンラインバンキングなどの標的ウェブサイトのウェブページに悪意のあるスクリプトを組み込むことで発生します。この例のスクリプトは、被害者の権限でバンキングアプリケーションにアクセスでき、機密情報の漏洩や、被害者の許可なく送金が行われる可能性があります。XSS脆弱性に対する重要な解決策の一つは、HTMLサニタイズです。
一部のブラウザには、攻撃者が悪意のあるスクリプトを含むURLを提供するリフレクション型XSS攻撃に対する部分的な保護機能が搭載されています。しかし、これらのブラウザのユーザーであっても、悪意のあるコードがデータベースに保存されるなど、他のXSS攻撃に対しては脆弱です。XSSを完全に防ぐには、サーバー側のWebアプリケーションを適切に設計する必要があります。
XSS脆弱性はブラウザ作者の実装ミスによっても発生する可能性がある。[ 89 ]
クロスサイト脆弱性のもう1つは、クロスサイトリクエストフォージェリ(CSRF)です。CSRFでは、攻撃者のサイト上のコードが被害者のブラウザを騙し、ユーザーが意図しない操作(銀行での送金など)をターゲットサイトで実行させます。ターゲットサイトがリクエスト認証にCookieのみに依存している場合、攻撃者のサイト上のコードから発信されたリクエストには、開始ユーザーの有効なログイン認証情報が含まれる可能性があります。一般的に、CSRFの解決策は、永続的な影響を与える可能性のあるリクエストを認証するために、Cookieだけでなく、隠しフォームフィールドにも認証値を要求することです。HTTPリファラーヘッダーをチェックすることも有効です。
「JavaScriptハイジャック」はCSRF攻撃の一種で、<script>攻撃者のサイト上のタグが被害者のサイト上のページを悪用し、JSONやJavaScriptなどの個人情報を返します。考えられる解決策としては、以下のようなものがあります。
クライアントサーバーアプリケーションの開発者は、信頼できないクライアントが攻撃者の制御下にある可能性があることを認識する必要があります。アプリケーションの開発者は、JavaScriptコードが意図したとおりに(あるいは全く)実行されると想定すべきではありません。コードに埋め込まれた秘密は、攻撃者によって抽出される可能性があるからです。その影響としては、以下のようなものが挙げられます。
npmやBowerなどのパッケージ管理システムは、JavaScript開発者に人気があります。これらのシステムを使用すると、開発者は自身のプログラムが他の開発者のプログラムライブラリに依存しているかどうかを容易に管理できます。開発者はライブラリのメンテナーがライブラリを安全かつ最新の状態に保ってくれると信頼していますが、必ずしもそうとは限りません。この盲目的な信頼が、脆弱性を生み出しています。依存しているライブラリが新しいリリースをリリースすると、そのライブラリを利用するすべてのプログラムにバグや脆弱性が現れることがあります。逆に、ライブラリがパッチ適用されずに、既知の脆弱性がそのまま放置されることもあります。13万3000のウェブサイトをサンプルとして調査した研究では、ウェブサイトの37%に少なくとも1つの既知の脆弱性を持つライブラリが含まれていることが判明しました。[ 92 ]「ALEXAでは、各ウェブサイトで使用されている最も古いライブラリバージョンとそのライブラリの最新バージョンとの間の平均遅延は1,177日であり、現在も使用されているライブラリの中には、開発が何年も前に終了しているものもあります。」[ 92 ]もう一つの可能性は、ライブラリのメンテナーがライブラリを完全に削除することです。これは2016年3月にAzer Koçulu氏がnpmからリポジトリを削除した際に発生しました。これにより、彼のライブラリに依存していた数万ものプログラムやウェブサイトが機能しなくなりました。[ 93 ] [ 94 ]
JavaScriptは幅広いブラウザ機能へのインターフェースを提供しますが、その一部にはバッファオーバーフローなどの脆弱性が存在する可能性があります。これらの脆弱性を利用することで、攻撃者はユーザーのシステム上で任意のコードを実行するスクリプトを作成できる可能性があります。このコードは、他のJavaScriptアプリケーションに限定されるものではありません。例えば、バッファオーバーランの脆弱性を悪用することで、攻撃者はスーパーユーザー権限でオペレーティングシステムのAPIにアクセスできるようになります。
これらの欠陥はFirefox、[ 95 ]、 Internet Explorer [ 96 ]、Safari [ 97 ]などの主要なブラウザに影響を与えています。
ビデオプレーヤー、Adobe Flash、Microsoft Internet Explorerでデフォルトで有効になっているさまざまなActiveXコントロールなどのプラグインにも、JavaScriptを介して悪用される可能性のある欠陥がある可能性があります(このような欠陥は過去に悪用されたことがあります)。[ 98 ] [ 99 ]
Windows Vistaでは、マイクロソフトはInternet Explorerのプロセスを制限された権限で実行することで、バッファオーバーフローなどのバグのリスクを抑制しようとしました。[ 100 ] Google Chromeも同様にページレンダラーを独自の「サンドボックス」内に制限しています。
ウェブブラウザは、サンドボックス外でJavaScriptを実行することができ、例えばファイルの作成や削除に必要な権限を持っています。しかし、このような権限はウェブ上のコードには付与されるべきではありません。
ウェブからJavaScriptに誤って権限を与えることが、Internet Explorer [ 101 ]とFirefox [ 102 ]の両方の脆弱性の一因となっています。Windows XP Service Pack 2では、MicrosoftはInternet ExplorerでのJScriptの権限を降格しました。[ 103 ]
Microsoft Windowsでは、コンピュータのハードドライブ上のJavaScriptソースファイルを、サンドボックス化されていない汎用プログラムとして起動できます(Windows Script Hostを参照)。そのため、JavaScript(VBScriptなど)は理論的にはトロイの木馬の攻撃ベクトルとなり得ますが、実際にはJavaScriptトロイの木馬は稀です。[ 104 ]
2015年には、セキュリティ研究者による論文で、 JavaScriptベースのRowhammer攻撃の概念実証実装が説明されました。 [ 105 ] [ 106 ] [ 107 ] [ 108 ]
2017年には、ブラウザを介したJavaScriptベースの攻撃がASLRを回避できることが実証されました。これは「ASLR⊕Cache」またはAnCと呼ばれます。[ 109 ] [ 110 ]
2018年に、Intelや他のプロセッサの投機的実行に対するSpectre攻撃を発表した論文にはJavaScriptの実装が含まれていました。[ 111 ]
重要なツールは言語とともに進化してきました。
JavaScriptはJavaと直接関連しているという誤解がよくあります。確かにどちらもC言語に似た構文を持っています(C言語は両者の最も直接的な共通祖先言語です)。また、どちらも一般的にサンドボックス化されており、JavaScriptはJavaの構文と標準ライブラリを念頭に置いて設計されています。特に、JavaのすべてのキーワードはオリジナルのJavaScriptでは予約語であり、JavaScriptの標準ライブラリはJavaの命名規則に従っており、JavaScriptのMathオブジェクトDateはJava 1.0のクラスに基づいています。[ 114 ]
どちらの言語も 1995 年に初めて登場しましたが、Java はSun Microsystems のJames Gosling氏によって開発され、JavaScript はNetscape Communications の Brendan Eich氏によって開発されました。
両言語の類似点よりも相違点の方が顕著です。Javaは静的型付けですが、JavaScriptは動的型付けです。Javaはコンパイルされたバイトコードから読み込まれますが、JavaScriptは人間が読めるソースコードとして読み込まれます。Javaのオブジェクトはクラスベースですが、JavaScriptはプロトタイプベースです。最後に、JavaはJava 8まで関数型プログラミングをサポートしていませんでしたが、JavaScriptはSchemeの影響を受け、当初から関数型プログラミングをサポートしています。
JSONはJavaScriptから派生したデータ形式であり、JavaScript Object Notation(JavaScriptオブジェクト表記)という名前が付けられています。JSONは広く利用されており、多くのプログラミング言語でサポートされています。
多くのウェブサイトはJavaScriptを多用しているため、他の言語で書かれたコードを変換して開発プロセスを支援するトランスパイラが作成されています。 [ 36 ]
TypeScriptとCoffeeScript は、JavaScript にトランスパイルされる 2 つの有名な言語です。
WebAssemblyは、JavaScript、特にウェブページスクリプトのパフォーマンスが重要な部分を補完するために設計されたバイトコード形式を持つ新しい言語です。主要なJavaScriptエンジンはすべてWebAssemblyをサポートしており、[ 115 ]通常のJavaScriptコードと 同じサンドボックス内で実行されます。
asm.jsはWebAssemblyの前身となったJavaScriptのサブセットです。[ 116 ]
: Netscapeが当面懸念したのは、Javaのように見えなければならないということでした。
:「function」は8文字で、AWKの影響を受けています。
1996年のJScriptバージョン1.0の導入以来、サーバー上でのJScriptの利用は着実に増加しており、特にActive Server Pages (ASP)で顕著です。
{{citation}}: CS1 maint: ISBNによる作業パラメータ(リンク)