JavaScript
読み:じゃばすくりぷと
外語:JavaScript

 Netscape Communicationsが開発した、Webブラウザースクリプト言語。現在では標準化されECMAScriptとなっており、このECMAScriptを意味する通称ないし俗称としてこの語が使われている。
目次

概要

由来と歴史

初出
 Netscape Navigator 2.0以降で採用された、HTML中に記述するスクリプト言語である。
 開発コード名は「Mocha」。当初は「LiveScript」という名になる予定だったが、営業戦略として、当時トレンドになりつつあったJavaの名前を冠した困った人がNetscapeにいたのでJavaScriptという名になってしまった。このJavaScriptという名はJavaの開発元Sun Microsystems(現Oracle)の合意を得て採用されており、このためSun(現Oracle)の商標となっている。
 この由来により、JavaScriptとJavaはほぼ関係がない。言語仕様にも共通性は特にない。従ってJavaScriptのことをJavaと呼ぶようなことはあってはならない。

歴史

古代
 1994(平成6)年、Netscape Navigator 1.0が登場し、人気を博した。
 その翌年1994(平成6)年5月にJavaが登場し、「動くWebサイト」に注目が集まり始める。同年8月、Internet Explorerが登場した。
 同年1995(平成7)年12月に、LiveScriptとして開発されていたJavaScriptを実装したNetscape Navigator 2.0が登場、これがインターネットの世界の一つの転機となった。
 翌年1996(平成8)年8月に、Internet Explorer 3.0が登場した。MicrosoftはJavascriptにライセンスの打診をしたがNetscapeはライセンス供与を拒んだため、代わりにJavascriptに似た何か「JScript」を搭載した。非ライセンス品だったこともあり互換性が著しく欠落しており、広く普及したInternet Explorerで動くものを書いてもNetscape Navigatorで動かない、あるいはその逆がよく発生するなどしたため、Webサイト作成者泣かせの存在になった。
 1997(平成9)年には動的にWebページを書き換えるDHTM(ダイナミックHTML)が流行した。ただこの頃は大した使い道があるわけではなく、主として装飾に使われ、さして必要性があるとは思えない無駄にアニメーションをするだけのページが量産されたためJavaScriptの評判は悪くなる一方だった。更にブラクラなる悪質なスクリプトが流行するに至り、JavaScriptはOFFにするのが当たり前の時代になった。代わりに、動くページはFlashで作ることが流行した。かくして、JavaScriptは要らない時代が長く続いたのである。

Ajaxの登場
 AjaxはWebブラウザー内で非同期通信をしてXMLを取得する技術で、2005(平成17)年にGoogleがGoogle Mapを発表したことで注目を集めた。このAjaxの実用化によりDHTMLも実用化されることとなり、結果としてJavaScriptが要らない時代は終焉、一時期は要らない子だったJavaScriptも無事に表舞台へと舞い戻り、第一線で活躍するプログラミング言語へと躍進したのである。
 同じ年2005(平成17)年にPrototype JavaScript Framework(prototype.js)が登場、2010(平成22)年にWebアプリケーションフレームワークのjQueryが登場し、Ajaxはじめ動的なWebサイト作りがより簡単になり、利便性の高いWebサービスが増えていった。

V8エンジンの登場
 V8と呼ばれる新規開発されたJavaScriptエンジンを搭載したGoogle Chromeが登場した。V8最大の特徴はJITコンパイラーを用いた仮想マシン型のJavaScript実行エンジンであり、従来の「Javascriptは遅い」という常識を覆した。
 こうしてGoogle Chromeは、かつてNetscape Navigatorを滅ぼし覇者となったInternet Explorerを、あっという間にインターネットから追い払ったのである。

JSフレームワーク時代
 かつてECMAScript第4版策定の場でMozilla(旧Netscape)陣営とMicrosoft陣営の主張が紛糾してから幾年月、JavaScrpitを取り巻く世界は大きく様変わりする中の2009(平成21)年、ようやくECMAScript第5版がまとまった。
 そして同じ年、V8 JavaScriptエンジン上に構築されたJavaScript実行環境Node.jsが登場した。Node.jsは、それまでWebブラウザー用のスクリプト言語だったJavaScriptをサーバーサイドスクリプティングとして使えるようにし、JavaScriptの常識をまた一つ塗り替えた。
 JavaScriptが普及し、Webサービスも複雑になるにつれ、Webアプリケーションの規模はどんどんと大規模なものになっていった。こういった大規模なアプリケーションでは、Backbone.js、Angular.js、React.js、Riot.jsといったWebアプリケーションフレームワークがフロントエンドで普及していった。

ECMAScript 2015登場
 2015(平成27)年6月、ECMAScript第6版となるECMAScript 2015が登場した。ECMAScript 2015はちまたに溢れるオブジェクト指向言語のトレンドを取り込んで、一気に近代的なプログラミング言語へと進化した。
 開発コードネームはECMAScript Harmoney(調和)とされ、かつて3.1派と4派で紛糾した仕様を、文字通り調和させたものとなった。
 これまでのJavaScriptとは大きく仕様が変わったことで、コーディングにおけるベストプラクティスもまた変化した。これ以降の新しいJavaScriptと、古いJavaScriptは、ここで分かれることになる。

言語仕様

基本コンセプト
 JavaScriptの言語的な特徴としては、次のようなものがある。

セミコロン
 JavaScriptはC系の言語であるので、行末にはセミコロン ; が必要である。
 但し、セミコロン ; を省いても、ある程度は自動的に解釈して補ってくれるという特徴がある。
 しかしこの場合、どこで文が切られるよう解釈されるかは全く直感的でなく、誤作動する場合はその影響範囲を探す手間ばかりかかる。従って、セミコロン ; は必ず書くべきである。余計な手間が増えてしまうことを考えれば、付けないという選択肢はない。

演算子

厳密等価演算子
 JavaScriptは動的型付け言語という時代遅れの設計がなされた言語であることが災いし型の概念が曖昧である。そこで「等しい」と判断するための基準が異なる、二種類の等価演算子が用意されている。
 JavaScript特有の === は厳密等価演算子と呼ばれ、型の種類まで一致するかどうかを確認する。対し == は、JavaScriptでは型を無視して概ね一致していればtrueになる。つまり、
 let str = undefined;
 if (str == null) { ... }
 のようなコードがもしあれば、このif文では比較がtrueになるため{}内が実行されてしまう。これで良い場合もあれば、そうでない場合もある。曖昧さを許容しない比較のために厳密等価演算子が存在する。

厳密不等価演算子
 同様、不等価演算子 != に対し、厳密不等価演算子は !== である。

真値(truthy)と偽値(falsy)

偽値(falsy)
 JavaScriptはプリミティブでtrueおよびfalseの論理値が定義されているが、論理値以外に偽値(falsy)として定義された値がある。それ以外は全てが真値(truthy)である。
 JavaScript(ECMAScript)が言語仕様として偽値と定義するのは次のもので、以下を除く全ての値は真値である。
 なお 0n はECMAScript 2020で導入されたBigIntの値である。記載はないが -0n も -0 と同様に偽値(falsy)である。
 ちなみに false == 0 は成立するが、null == 0 は成立しない。このあたりの根拠は不明確であるが以下のように対応している。x == yとした時の結果は次の通り。
x\yfalse0""nullundefinedNaN
falsetruetruefalsefalsefalse
0truetruefalsefalsefalse
""truetruefalsefalsefalse
nullfalsefalsefalsetruefalse
undefinedfalsefalsefalsetruefalse
NaNfalsefalsefalsefalsefalse
 結果として、trueになる比較条件は次の通りである。式の左右は入れ替えても同じである。
 なお、NaNに対するあらゆる比較については意味を持たない。これは言語仕様というよりはNaNというものの特徴である。詳細はNaNを参照のこと。
 またいずれも、厳密等価演算子===を用いれば異なる型の比較はfalseが返る。

真値(truthy)
 偽値(falsy)として定義されたもの以外の全ての値は真値である。
 従って以下は全てtrueと評価され、ifブロックが実行される(MDN Web Docs: Truthy (真値) より引用)。
 if文では、(0 == "0") は成立しtrueだが、if (0) と if ("0") は動作が異なる。これは数値の0は偽値(falsy)として定義されているが、文字列の"0"は偽値(falsy)としては定義されていないことによる。

if文の例
 ifでtrueと判定するのは、他の言語と同様にできる。
 if (obj == true) { ... }
 次のように書いても同様に機能する
 if (obj) { ... }
 いずれも比較は == であることに注意が必要である。JavaScriptにおいては、booleanプリミティブ型以外が真値か偽値かは全く直感的でなく、以下は成立する。
 let str = "";
 if (str == false) { ... }
 なぜなら、""は偽値だからである。
 こういった想定しない問題を起こさないため、厳密等価演算子を用いて次のいずれかの比較にした方がより安全である。
 if (obj === false) { ... }
 if (obj === true) { ... }
 また上述のように、undefined と null を等価演算子==で比較すると一致しtrueとなるなどの罠があるため、注意が必要である。

var、let、const
 JavaScriptにおける変数宣言は三種類ある。当初はvarだけだったが、ECMAScript 2015 (ES6) からletとconstが追加された。
 一度宣言して、再度同じ宣言ができる(再宣言ができる)のがvarの特徴である。
 var a = 0;
 var a = 1;
 console.log(a); // 出力は `1` となる
 しかし、これができること自体の利点はほぼ無く、バグの温床でしかない。なおかつvarのスコープは{}で囲ったブロックスコープではなく関数スコープつまり関数全体であり、悪影響が及ぶ範囲が広い。間違えて同じ変数名を用いてしまった場合、原因箇所の特定が難しいバグを生じさせる。このようにvarは予期しない不具合を招く危険が高い。
 結論からいうと、殆どのものはconstで定義できる(内容が変化する配列も参照である変数自体は変化しないのでconstでよい)。数え上げのための変数のみletを使えばよく、つまりvarはもう使う必要がない。

配列へのアクセス

forEach
 追加版は未確認だが遅くともECMAScript 2015 (ES6)以降なら利用できるのがforEachである。
 forEachは他のプログラミング言語にも見られるが、JavaScriptのこれはかなり個性的な仕様で、要素ごとにコールバック関数を呼び出す仕様である。
 const arr = ['AAA', 'BBB', 'CCC'];
 arr.forEach(function(elem, index) { ... });
 アロー関数を用いて次のように書くこともできる。機能は同じである。
 const arr = ['AAA', 'BBB', 'CCC'];
 arr.forEach((elem, index) => { ... });
 インデックスが不要の場合、アロー関数を用いれば更にシンプルに書くことができる。
 const arr = ['AAA', 'BBB', 'CCC'];
 arr.forEach(elem => ... );
 注意点として、このいずれの記法でもfor文のようにbreakすることはできない。returnはできるが、それをしてもfor文におけるcontinueと同じ機能にしかならない。
 ループ中にbreakやreturnを呼び出したい場合、従来通りのforループか、またはfor...of構文ループを使うか、あるいは目的に応じてsome、every、filterなどのメソッドを用いる。

some、every
 配列へのアクセスがチェック目的であるなら、forEachでなくてもsomeまたはeveryでその目的は代替できることが多い。
 const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 この場合、「要素が全て条件を満たす」か確認する場合はevery、「要素が一つでも条件を満たす」か確認する場合はsomeを使う。
 arr.some(value => value > 5) // →trueを返す
 arr.every(value => value > 5) // →falseを返す

filter
 配列へのアクセスが抽出目的であるなら、forEachでなくてもfilterでその目的は代替できることが多い。
 const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
 ここから5を超えるものを抽出する場合、次のいずれかの記法で解決できる。記法の近いだけで動作は全て同じである。
 const over5 = arr.filter(function(num) { return num > 5 });
 const over5 = arr.filter(num => { return num > 5 });
 const over5 = arr.filter(num => num > 5);
 下二つはアロー関数の記法だが、特に一番下はアロー関数のshorthandと呼ばれている。特に理由がない限りはshorthandを用いる方がシンプルでよい。

追加情報

方言
 JavaScriptには様々な方言がある。

関連技術

altJS
 JavaScriptの代替品となり、コンパイルしてJavaScriptが出力される言語を総じてaltJSという。
 次のような言語が代表的である。
 ただいずれも普及しているとは言い難く、大抵は何らかの欠点を持っていて常にオワコンの誹りを受けている。

フレームワーク・ライブラリー
 JavaScriptのフレームワーク・ライブラリーとしてよく使われているものは次の通り。
 jQueryはよく使われている、Webアプリケーション開発ではデファクトスタンダードとなっているJavaScript用ライブラリーであるが、規模の大きなWebアプリケーション開発ではもっと大きな枠組みまでサポートするMVCフレームワークとしてReactが使われる。
 その他に、既にレガシーなものも含め次のようなものがある。

フロントエンドWebアプリケーションフレームワーク
 Webアプリケーションを作る際に併用されることがあるもの。

その他のライブラリー
 その他、よく使われている代表的なライブラリーとして、次のようなものがある。

補足

用法
 具体的にはHTML中でscript要素を用いる。さらにtype属性でMIMEタイプを指定(JavaScriptは "text/javascript")を指定する。
 HTML中に記述することも、別途ファイルを用意して読み込むことも可能。
 古いNetscapeではlanguage属性でスクリプト言語の種類を指定していたために、古い書籍によってはlanguage="javascript"と書いているものがあるが、この記述法は既に古い。

普及
 JavaScript誕生後、Microsoftも対抗としてJScriptという互換品を作り、VBScriptと共にInternet Explorerで採用した。
 VBScriptはもちろん普及しなかったが、JavaScriptは普及、WWWにおける標準スクリプト言語となった。
 1997(平成9)年には情報通信の標準化団体ECMAが標準化を図る目的でECMAScript(ECMA-262)として標準化、今後も更にJavaScriptの改良が進む見通しである。

高速化

速度の需要
 JavaScriptの重要性は高まる一方である。
 AjaxはじめWebアプリケーションに無くてはならないものとなっただけでなく、HTML5との組み合わせで本格的なアプリケーションを作ることの出来るプログラミング言語となっている。
 しかも、パーソナルコンピューターから携帯電話機まで、あらゆるプラットフォームで利用できることも強みである。
 これがWebブラウザーでの処理速度の向上を強く後押しする結果となり、様々な技術を投入しJavaScriptの高速実行を達成させている。

技術

JITコンパイラー
 Javaの高速化などと同様、JavaScriptも一旦ネイティブコードを作って実行するJITコンパイラーが導入されている。
 一度に全部コンパイルする「メソッドベースJIT」と、特定箇所を重点的に高速化する「トレースJIT」が存在する。

GPUの利用
 JavaScriptをGPUで高速化しようとする試みもある。
 Webでは、動画、音楽などの処理が増え、三次元表示などをする例もある。こういったアプリケーションは今後も増えると見込まれ、GPUを用いた並列処理が研究されている。

実装

IE9
 マイクロソフトはInternet Explorer 9(IE9)で、これまでのJavaScriptエンジンを捨て、まったく新しいJavaScriptエンジンを開発、導入した。
 開発コード名はChakra(チャクラ)である。

Mozilla Firefox
 Mozilla Firefox 4は、二種類の方法を組み合わせる手法を採用した。
 多くのWebブラウザーと同様の、全てのJavaScriptコードを読み込んでコンパイルして実行するメソッドベースJITに、従来からの、特定箇所を重点的に高速化するトレースJITを組み合わせた。

Mozillaおよびその派生品

バージョン
 Netscapeによるバージョンは1.5までで、以降はFirefoxが勝手に(?)拡張を続けたものである。
 かつてはJavaScript 2.0を作ろうという動きが何度かあったが遂にまとまらず、実現しなかった。
 その間にECMAScriptがECMAScript 2015(いわゆるES6)が標準化され、以降はMozillaのJavaScript実装もECMAScript準拠を謳うようになり、もってJavaScriptとしてのバージョンは1.9が最終となった。

更新箇所

再検索