JavaScript
![]() JavaScript(ジャバスクリプト)は、プログラミング言語であり、HyperText Markup Language(HTML)やCascading Style Sheets(CSS)と並ぶ World Wide Web(WWW)の中核技術の一つである。 プロトタイプベースのオブジェクト指向スクリプト言語であるが、クラスなどのクラスベースに見られる機能も取り込んでいる。 利用される場面はウェブサイト、ウェブアプリケーション、バックエンド、デスクトップアプリケーション、モバイルアプリケーションなど、ウェブブラウザからサーバ、デスクトップパソコンからスマートフォンまで多岐にわたっている。 Javaと似た名称を持つが、異なるプログラミング言語である(#歴史を参照)。 概要JavaScriptはWebブラウザNetscape Navigatorに起源を持ち、現在では様々な用途に利用されるプログラミング言語である。 JavaScriptの言語仕様はECMAScriptとして標準化され、実装は各種のJavaScriptエンジンによって提供されている。JavaScriptエンジンの例としてChromium系ブラウザのV8、Mozilla FirefoxのSpiderMonkey、SafariのJavaScriptCoreが挙げられる。 言語仕様を定義するECMAScriptのほかに、WebブラウザへアクセスするためのAPI仕様にDOMなどがある。これらはECMAScriptから独立しており、JavaScriptからも独立した概念である。 プログラミング言語としての特徴JavaScriptは以下のような様々なスタイルのプログラミングが可能である。
これらを可能にしているプログラミング言語としての特徴に、以下のことが挙げられる。オブジェクト指向の面では、JavaScriptのオブジェクトはクラスベースではなくプロトタイプベースである[注釈 1]。関数型の面では、第一級関数をサポートし関数を第一級オブジェクトとして扱える。 AptanaやEclipse, NetBeans, IntelliJ IDEAなどの統合開発環境はJavaScriptをサポートしており、大規模開発が可能になっている。さらにExt JSなどの本格的なGUIライブラリの登場により、デスクトップアプリケーションと遜色ないユーザインタフェースの構築が可能になった。 並行処理JavaScriptではしばしば、ネットワークを介したリクエストのような "待ち" がある処理を行う[注釈 2]。これに対処するために非同期処理をサポートし並行処理が可能となる。標準で用意されている処理機能にも非同期処理されるものがある。 非同期処理を記述する方法としてコールバック関数がある。JavaScriptはコールバック関数記法をラップする またJavaScriptは並列処理による並行処理もサポートしている(下記参照)。 並列処理JavaScriptでは複数スレッドを用いた並列処理が可能である。共有メモリ上のバッファを表現する 歴史誕生JavaScriptはネットスケープコミュニケーションズのブレンダン・アイクによって、1995年5月に10日間で開発された。上司からの指示に「Javaのような外観にしてくれ」「初心者に優しく」「Netscapeブラウザのほとんどなんでも制御できるように」との注文があった[3]。Netscape Navigator 2.0で実装された。 開発当初はLiveScriptと呼ばれていたが、1995年にサン・マイクロシステムズ(現・オラクル)が開発したプログラミング言語Javaが当時大きな注目を浴びており、ネットスケープとサン・マイクロシステムズが業務提携していた事もあったため、JavaScriptという名前に変更された[4][5]。最初のJavaScriptエンジンはブレンダン・アイクによりNetscape Navigatorのために作成されたものであった。このエンジンはSpiderMonkeyと呼ばれており、C言語で実装されていた。また、全てJavaで記述されたJavaScriptエンジンであるRhinoも同じくNetscapeのNorris Boyd(後にGoogleに移籍)らにより作成された。 1996年にマイクロソフトのInternet Explorer 3.0にJScriptという名前で搭載されるようになると、その手軽さからJavaScriptは急速に普及していく。1997年、通信に関する標準を策定する国際団体EcmaインターナショナルによってJavaScriptの中核的な仕様がECMAScriptとして標準化され[6]、多くのウェブブラウザで利用できるようになった。 ネットスケープは、ウェブアプリケーション開発言語として自社のサーバ製品に実装したLiveWire JavaScriptも発表したが[5]、こちらはあまり普及しなかった。 JavaScriptの登場初期は、ブラウザベンダー間で言語仕様の独自拡張が行われていたため、ブラウザ間の互換性が極めて低かった。ECMAScriptの策定以降は実装間の互換性は向上し、DOMなど関連仕様の実装に関する互換性も高くなっていった。 かつてはJavaScriptという言葉が「ECMAScript標準」を指す、あるいは「独自実装を含んだ広義のJavaScript」を指し幅広い意味で使われていた。ゆえにどちらの意味でJavaScriptという言葉が使われているかは文脈で判断する必要があった[7]。たとえばかつてマイクロソフトによる実装はJScriptと呼ばれたが、JScriptをJavaScriptと呼ぶような場面があった。 ECMAScriptは仕様自体に独自の拡張を条件付きで認める記述があり[8]、ブラウザが実装しているスクリプト言語はすべてECMAScriptに準拠していることになる。広義の意味でこれをJavaScriptと呼ぶ場合、主要なブラウザが実装しているスクリプト言語はマイクロソフトやGoogle、Appleの実装も含めてJavaScriptである。 実装間での差異を吸収するためにPrototype JavaScript Frameworkなどのライブラリが用いられた。 発展市場のブラウザ間互換性がある程度確立された2000年ごろには、GoogleやAmazonなどのGAFAMもJavaScriptを積極的に利用し始めた。 また、JavaScriptはウェブブラウザの拡張機能を開発するための言語としても使われるようになった。当初は拡張機能用のAPIが統一されていなかったが、互換性を高めようとする動きがある[9]。 当初はインタプリタ方式で実行されることが一般的であったためJavaScriptの実行速度はさほど速くなかったが、現在ではJITコンパイルなどを利用した各種の最適化がなされており、各ウェブブラウザのベンダーともに高速化を図ってしのぎを削っている。さらには、この高速化を受ける形で、Node.jsのようにサーバサイドでもJavaScriptを使う動きが見られるようになった。 JavaScript 2.0次世代のJavaScriptとして、"JavaScript 2.0" を作ろうとした動きは二度あったが、いずれもまとまらなかった。 1度目はECMAScript 3が完成したのち2000年から2003年にかけて発生したが、ネットスケープとマイクロソフトの対立でまとまらなかった。当時ネットスケープが提案していた案はアドビのActionScript 2.0に引き継がれ、マイクロソフトの案はJScript .NETへと引き継がれた。 その後もネットスケープ及びMozilla FoundationはECMAScriptの策定に並行してJavaScriptを拡張し、JavaScript 1.x系列としてバージョンアップを繰り返していた。ECMAScript側ではECMAScript 4の策定が1999年以降進められており[10]、2006年の時点でMozilla Foundationはこれに基づいてJavaScript 2.0を作成することを表明していた。MozillaはECMAScript 4の策定にあたって、Pythonの文法を一部取り込んだ案を提案しており、自身でもこれを実装していた[11]。 しかしその後、ECMAScriptの標準化作業がMozilla, Adobe, Opera, Googleらが推す ECMAScript 4 と、Microsoft, Yahoo! らが推す ECMAScript 3.1 に事実上分裂してしまった影響から、2008年8月に大きな方針転換があり、ECMAScript 4は破棄され後者がECMAScript 5として2009年に標準化された。ECMAScript 4に入る予定だった機能は新たに発足した「ECMAScript Harmony」に先送りとなった[12]。これは後にECMAScript 2015として標準化が完了した。 なお、ECMAScript 5が標準化されて以降、MozillaのJavaScript実装はECMAScriptへの準拠を謳うようになった[13]。そしてバージョン番号での呼称は行われなくなり、JavaScript 2.0は事実上死語となった。 文法→詳細は「JavaScriptの文法」を参照
基本的な文法JavaScriptの変数は let x; // 変数xの宣言。値が未指定のため、特殊な値である undefined が入った状態となる。
let y = 2; // 変数yの宣言。同時に 2 が代入される。
const z = 5; // 定数zの宣言。同時に 5 が代入される。定数であるため、書き換えることはできない。
JavaScriptは言語仕様にI/Oが組み込まれておらず、それらは実行環境により提供される。ECMAScript 5.1の仕様では以下のように言及されている。[17]
しかし、ほとんどの実行環境はConsole Standard[18]で規定されている console.log("Hello World!");
再帰関数は以下のように書ける。 function factorial(n) {
if (n == 0) {
return 1;
}
return n * factorial(n - 1);
}
無名関数(またはアロー関数)の構文とクロージャの例は以下である。 // ECMAScript 5以前の記法
var displayClosure = function() {
let count = 0;
// ECMAScript 2015以降で可能な記法
return ()=> {
return ++count;
};
}
var inc = displayClosure();
inc(); // 1 が返る
inc(); // 2 が返る
inc(); // 3 が返る
var sum = function(...args) {
let x = 0;
for (const v of args) {
x += v;
}
return x;
}
sum(1, 2, 3); // 6 が返る
即時実行関数式 (IIFE) の例。関数を用いることで変数をクロージャに閉じ込めることができる。 var v;
v = 1;
var getValue = (function(v) {
return function() {return v;};
})(v);
v = 2;
getValue(); // 1 が返る
複雑な例以下のサンプルコードは、様々なJavaScriptの機能を示したものである。 "use strict"; // strictモードの宣言
/* 2つの数値の最小公倍数を求める */
function LCMCalculator(x, y) { // コンストラクタ関数
const checkInt = (x)=> { // 入れ子の関数
if (x % 1 !== 0) {
throw new TypeError(x + " is not an integer"); // 例外のスロー
}
return x;
};
// 行末のセミコロンは省略可能な場合があるが、省略は推奨されない。
this.a = checkInt(x)
this.b = checkInt(y);
}
// オブジェクトのプロトタイプはコンストラクタ関数の prototype プロパティに格納する
LCMCalculator.prototype = { // オブジェクトリテラル
constructor: LCMCalculator, // このようにプロトタイプを上書きする場合は、
// constructorプロパティにコンストラクタ関数名を再指定する
gcd: function () { // 最大公約数を計算するメソッド
// 「ユークリッドの互除法」アルゴリズムで計算
let a = Math.abs(this.a), b = Math.abs(this.b);
if (a < b) {
// 変数の入れ替え
const t = b;
b = a;
a = t;
}
while (b !== 0) {
const t = b;
b = a % b;
a = t;
}
// 最大公約数の計算は一度でよいため、自分自身を計算済みの結果を返すメソッドで再定義(上書き)する。
// (これにより LCMCalculator.prototype.gcd の代わりに this.gcd が呼ばれるようになる。
// ただし、計算後にプロパティ a や b が変更されてしまうと、結果は誤りとなる。)
// なお 'gcd' === "gcd", this['gcd'] === this.gcd である。
this['gcd'] = function () {
return a;
};
return a;
},
lcm : function () { // 最小公倍数を計算するメソッド
// 変数名は、オブジェクトのプロパティと衝突しない。例)lcm は this.lcm とは異なる。
// 以下では、浮動小数の精度の問題を避けるために this.a * this.b としていない。
const lcm = this.a / this.gcd() * this.b;
// 最小公倍数の計算も一度でよいため、自分自身を計算済みの結果を返すメソッドで再定義(上書き)する。
this.lcm = function () {
return lcm;
};
return lcm;
},
toString: function () { // toStringはオブジェクトを文字列に変換するときに呼ばれるメソッド。
// テンプレート文字列により文字列中に値を埋め込むことができる。
return `LCMCalculator: a = ${this.a}, b = ${this.b}`;
}
};
// 汎用の出力関数の定義。この実装はWebブラウザ上でのみ動作する。
function output(x) {
document.body.appendChild(document.createTextNode(x));
document.body.appendChild(document.createElement('br'));
}
// 無名関数はさまざまな書き方が可能
[[25, 55], [21, 56], [22, 58], [28, 56]].map(([a, b])=> new LCMCalculator(a, b)) // 配列リテラル + マッピング関数
.sort((a, b)=> a.lcm() - b.lcm()) // 指定した比較関数を用いたソート
.forEach(obj=> {
output(obj + ", gcd = " + obj.gcd() + ", lcm = " + obj.lcm());
});
上記コードをウェブブラウザ上で実行すると、以下の結果が表示される。 LCMCalculator: a = 28, b = 56, gcd = 28, lcm = 56
LCMCalculator: a = 21, b = 56, gcd = 7, lcm = 168
LCMCalculator: a = 25, b = 55, gcd = 5, lcm = 275
LCMCalculator: a = 22, b = 58, gcd = 2, lcm = 638
機能グローバルオブジェクトJavaScriptはコードの最上階層に属するグローバルオブジェクトを提供している。JavaScriptにおけるグローバルオブジェクトは エコシステム実行環境APIそれぞれのJavaScript実行環境において様々なAPIが存在しており、JavaScriptからそれらを呼び出すことができる。 WebブラウザHTML要素をJavaScriptから操作するためのDOM API(例: Node.jsファイルシステムにアクセスするための altJSalternative JavaScript (altJS) はJavaScriptへトランスパイルされるプログラミング言語の総称である。 JavaScriptへ新たな機能を追加する方法の1つに、新しい言語を定義しそのコードをJavaScriptへ変換する方法がある。そのようなJavaScriptへトランスパイルされる言語はaltJSと総称される。altJSの例としてCoffeeScriptやTypeScript、PureScriptが挙げられる。altJSを用いることで、新たな演算子や記法を導入し効率の良いJavaScript開発を行うことができる。素のJavaScriptはaltJSと対比してVanilla JSとしばしば呼ばれる[22]。 例えば、altJSの1つであるTypeScriptは型の導入を可能にする。JavaScriptは動的型付けであり、静的コード解析でJavaScriptコードへの型検査は実行可能だが、コード上に型表記をおこなうことはできないため、完全な型検査を行うことは難しい。TypeScriptはJavaScriptへ型ノーテーションを導入しトランスパイル時に型検査をおこなうことで、型をもったJavaScriptを実現している。 パッケージ管理JavaScriptエコシステムには多様なライブラリ(パッケージ)が存在する。パッケージの導入・バージョン調整・廃棄を担う管理ソフトウェアとして 利用WebブラウザにおけるHTML操作を目的として作られたJavaScriptは、2020年現在幅広い領域で利用されている。
Webページでの利用JavaScriptの最も歴史の長い使用法はHTMLページにクライアント側のふるまいを持たせることである。これは当初はダイナミックHTML (DHTML) として知られていた。JavaScriptはHTMLに直接埋め込まれまたは別のファイルからインクルードされ、Webブラウザ上のJavaScript実行環境で動作する。Webブラウザは通常、Document Object Model (DOM) を扱うためのホストオブジェクトを提供する。 JavaScriptの使用例としては、以下のようなものがある。
JavaScriptはユーザーのブラウザ上で動作できることから、ユーザーの操作に対して素早く反応することができ、アプリケーションをよりレスポンシブにすることができる。さらにJavaScriptはHTML単独では対応できない操作、例えばキー入力などにも応答することができる。Gmailのようなアプリケーションでは、JavaScriptでUIロジックを実装し、さらにJavaScriptでサーバから情報(例えばeメールのメッセージ)を取得することで、こうしたメリットを享受している。このような利点からAjaxは大きなトレンドとなった[要出典]。 様々な言語やフレームワークをウェブブラウザ上で動作させるために、JavaScriptはそれらのコンパイル先出力言語となっている(例: TypeScript)。 例以下はJavaScriptとDOMを含むWebページのごく単純な例である。
その他の環境での利用ウェブブラウザ以外のJavaScript実行環境も存在する(サーバーサイドJavaScript実装の一覧を参照)。データベースやWebサーバに組み込まれ、それらのAPIやHTTPリクエストやレスポンスのアクセスが提供されているものもある。 また、Node.jsのようにOSの機能(ネットワークやファイルシステムなど)にアクセスできる環境も存在する。加えてElectronなどのアプリケーションフレームワークの登場により、Atomなどのアプリケーションが広まりつつある。 いくつかのアプリケーションではマクロ言語としても採用されている。例えばAdobe Acrobatは、JavaScriptによるマクロ機能を搭載している。 バージョンとブラウザの対応表→「ECMAScript § バージョン」も参照
ライブラリ代表的なJavaScriptライブラリは以下のとおり。 商標「JavaScript」は米国では、米国オラクルの商標である[26][27][28]。この商標はもともと1997年5月6日にサン・マイクロシステムズに発行され、2009年にオラクルがサンを買収した際に譲渡された[29]。 2024年9月にはライアン・ダールが先頭に立ってオラクルにJavaScript商標の解放を求める書簡が回覧された[30]。JavaScriptの生みの親であるブレンダン・アイクもこの取り組みを支持した14,000人以上の署名者の1人だった。 脚注注釈出典
関連項目
外部リンク
|
Portal di Ensiklopedia Dunia