Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.
JavaScript(別名:Mocha、LiveScript、JScript、ECMAScript)は、世界で最も人気のあるプログラミング言語の一つです。世界中のほとんどのパソコンには、少なくとも1つはJavaScriptインタープリタがインストールされ動いていることでしょう。JavaScriptは、WWWのスクリプト言語としての確かな地位により広く利用されるようになったのです。
しかしその高い普及率にもかかわらず、JavaScriptが汎用的でダイナミックな優れたオブジェクト指向プログラミング言語であることはあまり知られていません。
どうして、その素晴らしさが認められないのでしょう?また、なぜ、JavaScriptは誤解されるのでしょうか?
Javaという接頭語は、Javaと関係があったり、あるいはJavaのサブセット、または性能の低いJavaのバージョンであるかのように思わせます。混乱させるために、わざとその名前がつけられたような気さえします。そして、その混乱が誤解を生むのです。
JavaはJava実行環境で動作しますが、JavaScriptは違います*1。JavaScriptは、Javaとは異なる言語なのです。
JavaがCに類似する構文を持っているのと同程度に、JavaScriptとJavaの構文は似ています。しかし、JavaがCのサブセットではないように、JavaScriptもJavaのサブセットではないのです。Java(その当時はOak)が、元々ターゲットとしていたような種類のアプリケーションを構築する場合でも、JavaScriptはJavaより優れています。
JavaScriptは、Javaを作ったSun Microsystems社ではなく、Netscape社により開発されました。最初はJavaが先頭に付かずにLiveScriptと呼ばれていましたが、それでも少し紛らわしいと思います。
そもそもScriptという接尾語は、JavaScriptが本物のプログラミング言語ではなかったり、あるいはスクリプト言語はプログラミング言語より劣るかのように思わせるふしがあります。
しかし大事なことは、どこに特化するかです。JavaScriptは、C言語の実行速度と引き換えに、表現力とダイナミズムを手に入れたのです。
JavaScriptには、Cのような中括弧や不格好なforステートメントがあるため、一般的な手続き型言語のように見えますが、それは誤りです。JavaScriptはCやJavaよりも、LispやSchemeのような関数型言語と多くの共通点を持っているのです。JavaScriptには、リストの代わりに配列があり、プロパティリストの代わりにオブジェクトがあります。関数はファーストクラスであり、クロージャも備えています。つまり括弧の対応をとる手間なしに、ラムダを利用できるのです。
JavaScriptは、Netscape Navigatorで動くように考案されました。そしてその成功により、JavaScriptの実行環境は、ほぼすべてのウェブブラウザに標準的に装備されるようになったのです。結果として、これによりJavaScriptのイメージが固定化されてしまいました。JavaScriptはプログラミング言語のスーパーマンです。ウェブではない多くのアプリケーションにも、JavaScriptは良く合うでしょう。
最初のバージョンのJavaScriptは非常に機能が低く、例外処理、内部関数、そして継承もありませんでした。現在のバージョンのJavaScriptは、完全なオブジェクト指向プログラミング言語です。しかしJavaScriptに関する評価の多くは、この初期の低機能なバージョンに基づいたものです。
JavaScriptの管理を行なうECMA委員会は、機能の拡張を続けています。確かにその拡張はよく考えられてはいるのですが、沢山のバージョンがありすぎるという大きな問題を悪化させることになります。これは、更なる混乱を生むことになるでしょう。
完全なプログラミング言語などありません。JavaScriptにも、他言語同様に設計のミスがあります。例えば、型変換によって加算と連結の意味が使い分けられる、 + のオーバーロードが挙げられます。また、エラーを引き起こしやすいwithステートメントは避けられるべきものでした。予約語の規定は厳し過ぎますし、正規表現リテラルの表記方法とセミコロンの挿入も大きな誤りでした。これらの誤りは、プログラミングエラーを引き起こし、言語の設計自体に疑問を抱かせることとなりました。幸い、良い構文チェックプログラム(JSLint)によって問題の多くを軽減することができます。
全般的にはJavaScriptの設計はとても正しいと思っています。でも驚いたことに、ECMAScript委員会は、先ほど挙げたような問題を修正することに興味がないようなのです。多分、彼らは新しい問題を作る方により興味があるのでしょう。
JavaScriptの初期の実装にはバグの多いものがありました。これは、JavaScriptに悪い印象を抱かせることになりました。*2更にまずいことに、その実装は恐ろしくバグの多いウェブブラウザに埋め込まれてしまったのです。
JavaScriptに関する書籍の大半は非常にひどいものです。それらの書籍は間違いと下手な実例を記載し、悪い習慣を助長しています。たいていの場合、JavaScriptの重要な特徴の説明が不十分か、または完全に省略されています。私は沢山のJavaScriptの本を読んできましたが、お勧めできる書籍は2冊しかありません。『JavaScript』著:デイビッド・フラナガンと、『Dynamic HTML (2nd Edition)』著者:Danny Goodman*3です。両方ともオライリーから出版されています。
JavaScriptの公式仕様書はECMAが発行しています。この仕様書の品質は非常に悪いです。これを読み進めるのは難しく、内容を理解するのは極めて困難です。JavaScript関連書籍の作者達が、自分自身の理解を深めるためにJavaScriptの公式仕様書を使用できないことが「ひどい書籍」の問題を引き起こしているのです。ECMAとTC39委員会は、深く反省するべきだと思います。
JavaScriptを書く人の多くはプログラマではありません。彼らは良いプログラムを書くための教育と規律が欠如しています。しかしJavaScriptの豊かな表現力を使って、彼らはやっつけで仕事を片付けることができます。そのため、JavaScriptが完全にアマチュア向けであり、プロフェッショナルなプログラミングには適していない、という評判をもたらしました。これは事実とは全く異なります。
JavaScriptはオブジェクト指向でしょうか?
JavaScriptにはオブジェクトがあり、オブジェクトはデータと、データに作用するメソッドを含むことができます。オブジェクトは他のオブジェクトを含むこともできます。
JavaScriptにはクラスがありませんが、クラスに相当する機能としてコンストラクタが存在します。コンストラクタは、クラス変数とメソッドのコンテナとして機能します。また、JavaScriptはクラス指向の継承ではなく、プロトタイプ指向の継承を備えています。
オブジェクトを組織する2つの主な方法に*4、継承(is-a)と集約(has-a)があります。JavaScriptでは両方を使うことができるのですが、この言語の持つ動的な性質を考えると、集約の利用が勝っているでしょう。
JavaScriptは情報の隠蔽を行なえないので真のオブジェクト指向ではない、という主張があります。この主張は、オブジェクトがプライベート変数とプライベートメソッドを持てず、すべてのメンバがパブリックになってしまうというものです。
しかしJavaScriptのオブジェクトも、プライベート変数とプライベートメソッドを持てることが分かりました。(ここをクリックして、確認してください。)もちろん、JavaScriptは世界で最も誤解されたプログラミング言語であるため、理解している人はほとんどいません。
JavaScriptには継承がないので、真のオブジェクト指向ではない、という主張もあります。
しかしJavaScriptが古典的な継承だけでなく、その他のコード再利用パターンも使えることが分かっています。
*1:JavaScript is not interpreted Java.Java is interpreted Java.
*2:This reflected badly on the language.
*3:日本語版の存在不明。同著者の『JavaScript & DHTMLクックブック』が出版されている。
*4:The two main ways of building up object systems