Java 開発 2.0: Java 開発者のための JavaScript

Java 開発者のための JavaScript の変数、型、関数などの基本事項の説明

かねてから Java 開発者は JavaScript のことを、実際のプログラミングには軽量すぎるだけでなく、スクリプトを記述するための代替手段として使うにも魅力のない、おもちゃのような言語であると見なしてきました。それにもかかわらず、JavaScript は未だ健在であり、しかも GWT や Node.js などの画期的な Web 技術の基礎として使われています。連載「Java 開発 2.0」の今回の記事では、Andrew Glover が現在の Java 開発者にとって JavaScript が重要なツールである理由を説明します。その後、JavaScript の変数、型、関数、クラスを含め、最近の Web で極上のアプリケーションを構築するために必要となる構文について手ほどきします。

Andrew Glover, Author and developer, Beacon50

Andrew GloverAndrew Glover は、ビヘイビア駆動開発、継続的インテグレーション、アジャイル・ソフトウェア開発に情熱を持つ開発者であるとともに、著者、講演者、起業家でもあります。また、easyb BDD (Behavior-Driven Development) フレームワークの創始者、そして『継続的インテグレーション入門 開発プロセスを自動化する47の作法』、『Groovy in Action』、『Java Testing Patterns』の 3 冊の本の共著者でもあります。詳細は彼のブログにアクセスするか、Twitter で彼をフォローしてください。



2011年 6月 03日

Java プラットフォームが登場してまもない頃は、ジャーナリストだけでなく、新米プログラマーでさえも JavaScript と Java 言語を混同することは珍しくありませんでした。どちらの言語も Web プログラミングに適用できることから普及する結果となり、最初の数年間はこの 2 つがツバ競り合いを演じていたというのが一般的なイメージです。現在は、ほとんどの人々がこの 2 つの言語を区別するようになっていますが、Java 開発者は依然として JavaScript のことを、スクリプトを記述するのにも向かない、おもちゃのような言語であると冷笑しています。それでもまだ、JavaScript は (Java 言語と同じように) 生き延びていて、進化さえしているというのが事実です。JavaScript は Ajax のようなクライアント・サイドのプログラミング手法でも、Node.js などのサーバー・サイドの取り組みでも基礎として使われており、モバイル・アプリケーション開発での重要性が明らかになり始めています。さらに、非常によく使われている GWT (Google Web Toolkit) でも、Java コードはコンパイルされて JavaScript にされます。

連載「Java 開発 2.0」の今回の記事では、現在 JavaScript が Java 開発者にとって重要である理由を説明し、最も役立つ JavaScript 構文をいくつか紹介するなかで、Java 言語との違いを説明するとともに、JavaScript を Groovy や Ruby などの比較的最近の動的言語と比べます。

この連載について

Java 技術が初めて登場してから現在に至るまでに、Java 開発の様相は劇的に変化しました。成熟したオープンソースのフレームワーク、そしてサービスとして提供される信頼性の高いデプロイメント・インフラストラクチャーを利用できる (借りられる) おかげで、今では Java アプリケーションを短時間かつ低コストでアセンブルし、テスト、実行、保守することが可能になっています。この連載では Andrew Glover が、この新たな Java 開発パラダイムを可能にする多種多様な技術とツールを詳しく探ります。

当時と現在: JavaScript が重要である理由

Netscape が 1995年に発表した JavaScript は、瞬く間に人気が上がりました。その理由は、商用メディア・プラットフォームとしての Web の出現と大いに関係します。今でもそうですが、JavaScript を使用すれば、ブラウザー内での Web ページの振る舞いをプログラムで変更することができます。当時としては、それは目を見張る機能でした!その頃、重要視されていたのは、HTML フォームの検証とわずかながらの画像トリックだったからです。

その後、JavaScript は何度か転換期を迎えます。Netscape はある時期、サーバー・サイドの JavaScript を利用して Web アプリケーションを構築する Netscape Application Server という製品を提供していました。それから数年後、Ajax の登場、そして Prototype、JQuery、Extjs などのウィジェット・ライブラリーの登場により、JavaScript には新たな関心が寄せられましたが、最近になって、サーバー・サイドの JavaScript の時代に戻ってきました。そのきっかけとなったのは Node.js です。Node.js は、Google の V8 JavaScript エンジンを使用してサーバー・サイドの Web アプリケーションを構築するためのイベント駆動型 I/O フレームワークです。

Netscape はその将来を考慮した先進的な行動として、JavaScript を標準化すべく、Ecma International に提出しました。これが、一部の人々が JavaScript を ECMAScript と呼んでいる理由です。さらに重要な点として、大部分の Web ブラウザーが ECMAScript をサポートしているのも、これが理由です。その結果、Web アプリケーションはどこかしらで JavaScript を使用しないわけにはいかなくなっていますが、この事態は変わりそうにありません。今のところ、他のブラウザー対応スクリプト言語が登場する兆しはないからです。

Node.js

Node.js (「参考文献」を参照) は、並行性に優れたサーバー・サイドのイベント駆動型フレームワークです。Node.js プログラムはスレッドを使用するプログラムよりも遥かに効率的にスケーリングできると同時に、並行プログラミングに伴う多くの問題に対処します。Node.js は比較的新しいものの、このフレームワークを中心とした技術革新は活気に満ちています。増加しつつある Node.js 関連のツール群を使用するには、JavaScript を知ることが鍵です。

その悪評はなかなか消えないながらも、JavaScript は現在、地球上で最もよく使われている (そして役に立つ) 言語の 1 つであると言ってほぼ間違いありません。Java プログラマー (あるいは Ruby、Python、または PHP プログラマー) であれば、過去に JavaScript を使用したことがあるか、そうでなくても近い将来、JavaScript を使用することになるはずです。JavaScript の機能のいくつかを理解しておけば、次の超人気の Web アプリケーションを構築する助けとなるだけでなく、Node.js を使用できるようにもなります。さらに、GWT の内部で何が行われているのかをより深く理解することもできます。

以降のセクションでは、JavaScript 構文の主要な要素に焦点を当て、Java 開発者をとりわけ驚かせたり、喜ばせたりすることになる Java 言語との細かな違いを浮き彫りにします。けれどもまずは、JavaScript にまつわる誤った通念の 1 つを払い除けさせてください。それは、JavaScript を扱うには Web ページが必要であるという思い込みです。


Chrome で使用する JavaScript

従来、JavaScript を実行するにはブラウザー (間接的には Web ページ) が必要でした。一部の開発者には、この点が頭痛の種であり、障害となることさえありました。幸いブラウザーは進化し、今では Firefox と Chrome の両方に JavaScript を実行するための IDE が用意されています。

私が JavaScript 言語をいじくりまわすためのツールとして気に入っているのは、Chrome の気の効いた JavaScript コンソールです。Ruby の IRB や Python のシェルのように、Chrome が提供するインタラクティブな環境では Web ページを使わずに JavaScript を詳しく調べることができます。

CoffeeScript

JavaScript の機能は気に入っていても、その構文が気に入らないという場合には、CoffeeScript を調べてみてください。CoffeeScript は「コンパイルすると JavaScript になる簡易言語」です。つまり、CoffeeScript は JavaScript の構文の一部を緩和することで、JavaScript プログラミングを容易にします。多くの点で、CoffeeScript は Ruby や Python のような感がありますが、CoffeeScript は JavaScript と 1 対 1 で対応します。CoffeeScript についての詳細は、「参考文献」を参照してください。

Chrome の JavaScript コンソールを使用するには、OS に対応する Chrome をダウンロードする必要があります。次に、新しい空白タブ (つまり、Web ページを指していないタブ) を開き、「View (表示)」 > 「Developer (開発者)」 > 「JavaScript Console (JavaScript コンソール)」の順に選択します。すると、Chrome ウィンドウの下部に JavaScript 開発者用コンソールが表示されます。このコンソールの左下隅にあるドック解除アイコンを選択すれば、コンソールをスタンドアロンのダイアログにすることができます。そしてダイアログの右上隅にあるコンソール・アイコンを選択すると、JavaScript を扱うためのシンプルな空白ウィンドウが表示されます (図 1 を参照)。

図 1. Google Chrome で JavaScript を扱う
Google Chrome の JavaScript コンソールを示すスクリーン・ショット

それでは早速、構文を見ていきましょう。


JavaScript の変数

プログラミングにかなり多くの間違いがあったとしても Web ページがロードされるという点で、JavaScript はかなりおおらかな言語です。JavaScript の要素は暗黙のうちに失敗することがよくありますが、これは大方のところ、好ましいことです。ずさんな JavaScript プログラミングによってページをロードできなかったとしたら、初期の頃の Web が現在のように開拓されることはなかったでしょう。それはそうですが、私たちはそれよりも手が込んだこと (非同期にページの状態を更新するなど) を行うために JavaScript を利用しているので、不注意な JavaScripting が大打撃を与えることは確かです。このことから、Java 開発者は、JavaScript 構文が持つ特定の側面をしっかり理解するために時間を割く必要があります。

特に理解しておかなければならないのは、JavaScript での変数の扱い方です。例えば foo という名前の変数を定義するとしたら、この変数を直接定義することも、var 宣言によって定義することもできます (リスト 1 を参照)。

リスト 1. foo 変数
foo = 'foo'
var bar = 'bar'

リスト 1foo は、JavaScript で有効な変数です。ただし、var 宣言が欠けているため、これはグローバル変数となります。var を使用して変数を定義した場合には、その変数にスコープが設定されます (例えば、変数が関数内で定義された場合には、その変数のスコープはその関数に設定されます)。

一般に、グローバル変数は好ましいものではなく、大抵は「コードの臭い」の発端となります。つまり、グローバル変数には JavaScript アプリケーションのどこからでもアクセスして変更できるため、グローバル変数の使用によって、たちの悪いバグがもたらされる可能性があります。したがって、JavaScript でプログラミングするときには、変数に var を指定することを忘れないでください。


プリミティブとオブジェクト

JavaScript は決して単純なわけではありませんが、こと型に関してはかなり単純です。実のところ、JavaScript には 3 つはプリミティブ型を含め、4 つの基本型しかありません。JavaScript のプリミティブ型は、Number (数値型)、String (文字列型)、および Boolean (ブール型) です。これらの型を実際に確認するには、JavaScript の重宝な演算子、typeof を使用することができます。

早速、この演算子を試してみましょう。Chrome の JavaScript コンソールに、リスト 2 に記載されている内容を入力してください。

リスト 2. 型の確認
var string = "test"
typeof string

コンソールには、”string” という値が出力されます。また、上記のコードから、JavaScript ではセミコロンがオプションであることもわかるはずです。よく使われているほとんどの言語でそうであるように、文字列は引用符で表現されます。数値は当然、数値によって表され、ブール値は引用符なしの true または false の値で表されます。

リスト 3. JavaScript の真理値と数値
var aNumber = 10
var anotherNumber = 0.99
var aBool = true
var notABoolean = "false"

上記からわかるように、JavaScript では数値の型は区別されません。数値は数値であり、単にフォーマットが異なるだけに過ぎません。

JavaScript は汎用オブジェクトもサポートし、汎用オブジェクト自体にインスタンス・タイプがあります。これらのインスタンス・タイプの 1 つは、リスト 4 に示す配列です。

リスト 4. 配列のインスタンス
> var myArray = ["Hello", 1, true]
> typeof myArray
"object"
> myArray instanceof Array
true

JavaScript での配列は他の言語でのリストとよく似ていて、サイズ制限なしで作成して、そこにスローしたいものを何でも保持させることができます。Ruby や Groovy と同じく、JavaScript の配列を作成するにはリテラル構文、[] を使用することができます。さらに、リストをサポートする他の言語で当たり前になっているように、JavaScript の配列はメソッドをサポートします (リスト 5 を参照)。

リスト 5. 配列のメソッド
> var myArray = ["Hello", 1, true]
> myArray[0]
"Hello"
> myArray.length
3
> myArray.pop()
true
> myArray
["Hello", 1]
> myArray.pop()
1
> myArray
["Hello"]
> myArray.push("pushed")
2
> myArray
["Hello", "pushed"]

配列の値は、位置 (ゼロを基準とします) によって取得することができます。配列は push および pop に応答します。push の場合には項目が (最後の位置に) 追加され、pop の場合には (スタックと同じように、最後の位置から) 項目が削除されます。

配列は繰り返しもサポートします (リスト 6 を参照)。

リスト 6. 配列の繰り返し処理
> var myArray = [1,2]
> for(var i = 0; i < myArray.length; i++) { console.log(myArray[i]) }
1
2

型の強制

JavaScript は単に弱い型付けの言語というだけでなく、その型付けの弱さは Ruby や Groovy さえも上回るほどです!JavaScript はわざわざ、コード内のある特定の箇所で妥当な型になるようにオブジェクトを強制します。これは、JavaScript が元々考え出されたコンテキスト、つまり Web ページとの対話では理にかなったことです。ずさんな JavaScript でも、それによってユーザーがオンライン記事を読むことができないようであってはなりません。

型の強制は JavaScript に特有なことではありませんが、JavaScript の場合は極めて柔軟です。見方によっては、この柔軟性は利点にもなれば、欠点にもなります。グローバル変数がそうであるように、JavaScript の規則の緩さは問題を見えなくする可能性があります。

例えば、配列を定義した後、うっかりこの配列に対して数値的な操作を行おうとしたり、さらには文字列の連結を実行したりしようとする場合が考えられます (リスト 7 を参照)。

リスト 7. JavaScript の型の柔軟性
> var myArray = [1,2]
> console.log(2 * myArray)
> console.log("A" + myArray)

この場合、最初のログ・メッセージには「NaN」と出力され、2 番目のログ・メッセージには「A1,2」と出力されます。いずれの場合も、エラーにならずに JavaScript がそのまま実行され続けるという点で、このコードは「機能した」ことになります。これは極端に弱い型付けで、同じコードを Ruby で作成したとすると、同じようにはなりません (リスト 8 を参照)。

リスト 8. 同じようには振る舞わない Ruby
> array = ["A", "B"]
> ans = 2 * array

リスト 8 の Ruby コードは、以下のエラーを出します。

TypeError: Array
can't be coerced into Fixnum

array"A" を追加しようとすると、以下の結果になります。

TypeError: can't convert
Array into String

同じことを Groovy で試したとすると、以下のような結果になるはずです。

groovy.lang.MissingMethodException: No signature of method: 
java.lang.Integer.plus() is applicable for argument types: (java.util.ArrayList) values:
[[A, B]]

このように、弱い型付けにはさまざまなレベルがあります。型付けの弱さに尺度があるとしたら、この 3 つのうちで最も弱いのは JavaScript であることは確かです。


JavaScript の関数

JavaScript の関数は、Java のメソッドと同じく、再利用可能な振る舞いを定義してカプセル化するための構成体です。JavaScript での関数のルック・アンド・フィールは、一見すると Groovy のクロージャーによく似ています。JavaScript では、関数はオブジェクトです。実際、関数はファーストクラスのオブジェクトであり、Java コードでのメソッドとはまったく似ていません。JavaScript 関数はオブジェクトであることから、他の関数に渡すことも、意のままに呼び出すこともできます。

関数を定義するには、function キーワードを使用します。Java 言語でのメソッド宣言と同じように引数を指定できるだけでなく、JavaScript 関数から何かを返すこともできます。Groovy や Ruby などの動的言語では return 呼び出しはオプションですが (したがって、メソッドの最後の行が返されます)、JavaScript での関数が何かを返さなければならない場合は、return 文を使用する必要があります。そうでないと、関数は何も返しません。

JavaScript で関数を呼び出す方法は、Groovy でクロージャーを呼び出す方法と同様です。リスト 9 に、パラメーターを 1 つも取らない単純な関数を定義します。この関数の目的は、Chrome の JavaScript コンソールに「blah」と出力することです。

リスト 9. JavaScript での関数の定義と呼び出し
> function blah() { console.log("blah"); }
> blah() //prints blah
> blah.call() //prints blah
> blah.apply() //prints blah

関数を直接呼び出すには、括弧 (つまり ()) を使用します。関数は、call メソッド、または apply メソッドを介して呼び出すこともできます。ここに、関数オブジェクトがファーストクラスであることが明確に示されています。リスト 10 に、blah 関数で関係のないメソッドを呼び出そうとするとどうなるかを示します。

リスト 10. JavaScript でのオブジェクトとしての関数
> blah.foo()

この場合、foo は定義されているメソッドではないというエラー・メッセージが表示されます。

TypeError: Object function blah() { console.log("blah"); } has no method 'foo'

上記のエラー・メッセージをもう一度読んでください。このメッセージは、foo が「定義されて」いないと言っています。つまり、これが定義されていたとすれば、正常に実行されていたということです。


JavaScript でのクラス

前述したように、JavaScript はプリミティブをサポートします。また、配列などのオブジェクトもサポートします。しかし、JavaScript はクラスをサポートしません。少なくとも、従来の Java 言語で言うクラスはサポートしません。JavaScript はプロトタイプ・ベースの言語であるため、クラスを定義するのではなく、既存のオブジェクトを複製することによって振る舞いを再利用します。したがって、JavaScript ではクラス・オブジェクトは定義せず、関数の中に既存のオブジェクトを複製して定義し、これらの関数をネストすることによって振る舞いを定義します。これが実際に目にしたことがある定義の仕組みです。

クラスを模倣するには、関数を定義します。関数には名前を付けて (つまり、クラス名)、パラメーターを指定することができます (コンストラクターでの場合と同様)。さらには、.this キーワードを使用することもできます。これはつまり、関数のスコープ内で変数を参照するということです。その上、内部関数に別名を指定してメソッド呼び出しのように見せることもできます。

具体的な例として、リスト 11 に非常にシンプルな Message プロトタイプ (別名、クラス) を作成します。このクラスにいくつかのパラメーター (メッセージの送信者、宛先、実際のメッセージ) を設定し、クラスがメッセージを JSON として表現するようにします。

リスト 11. JavaScript でのクラスとしての関数
function Message(to, from, msg){
 this.to = to;
 this.from = from;
 this.msg = msg;

 this.asJSON = function(){
  return "{'to':'" + this.to + "', 'from':'" + this.from + "', 'message':'" +
    this.msg + "'}";
 }
}

リスト 11 では、Message 関数を定義しました。この名前付きオブジェクトには、tofrom、および msg というプロパティーがあります。次に定義したプロパティー (asJSON) は内部関数を指します。その役割は、JSON メッセージのストリング表現を組み立てることです。

この「クラス」は、Web ページにも定義できることに注意してください。その場合、Chrome でロードして JavaScript コンソールを開き、そのコンソール上でインタラクティブに使用することができます。それが、リスト 12 の内容です。

リスト 12. JavaScript でのクラスの使用
> var message = new Message('Andy', 'Joe', 'Party tonight!');
> message.asJSON();
"{'to':'Andy', 'from':'Joe', 'message':'Party tonight!'}"

このコードは Groovy とほとんど同じで、(var がなければ) Java コードにも似ていると思いませんか?実際のところ、OOP (Object Oriented Programming: オブジェクト指向プログラミング) 手法を使用して JavaScript アプリケーションを構築することも可能です (つまり、データとメソッドを持つオブジェクトが互いにやりとりするプログラム)。


まとめ

この記事を読んで、JavaScript はおもちゃのような言語であるという、今ではすっかり時代遅れとなったイメージがなくなったことを願います。実際、JavaScript は非常に強力な言語であり、Groovy や Ruby などの比較的新しい言語のようにシンタックス・シュガーに溢れ、簡単に使用することができます。90 年代に JavaScript を疑問視させたいくつかの性質そのものが、今では魅力として受け取られています。

ほとんどの Java アプリケーション開発にとっての Web の重要性と、JavaScript が持つブラウザー対応言語としての独特のポジションを考えると、あらゆる Java プログラマーは JavaScript に精通するべきであるというのが結論です。アプリケーションを操作する手段として、(コンピューター、モバイル機器、電話、タブレットのどこに搭載されているかにかかわらず) ますます多くの人々がブラウザーを使用するようになっています。JavaScript も同じく、すべてのサーバー・サイド言語との間を取り持つ共通の手段です。それに加え、JavaScrip が持ついくつかの機能を理解しておくことが、Java 言語を含め、どの言語であってもプログラマーとしての腕を上達させることになります。

参考文献

学ぶために

  • 連載「Java 開発 2.0」: この連載では Java 開発の様相を塗り替える技術を詳しく探っています。これまでに取り上げた話題には、Google App Engine (2009年8月)、NoSQL (2010年5月)、Amazon Elastic Beanstalk (2011年2月) などがあります。
  • Why You Need to Learn JavaScript」(Michael Woloszynowicz 著、Web Development 2.0 and Business Lessons、2011年1月): Java プログラミングを熟知した開発者たちが重要なスキルを JavaScript に提供し、JavaScript が Web およびモバイル・アプリケーション開発に不可欠なツールを提供することになります。
  • コンパイラのターゲットとしてのJavaScript:Clamato、GWT Smalltalk、Python、Scheme」(Werner Schuster 著、InfoQ、2009年9月): JavaScript を現代に合わせてモバイルおよび Web アプリケーション開発に利用できるようにしている最近のツールについて調査しています。
  • Ryan McGeary on CoffeeScript」(developerWorks、2011年2月): McGeary 氏が、Node.js をベースに作成され、JavaScript へのコンパイルを行う CoffeeScript が関数型プログラミングを簡潔化し、より読みやすい JavaScript を生成する仕組みを解説しています。
  • Why You Should Pay Attention to Node.js」(Stephen O'Grady 著、RedMonk Tecosystems、2010年5月): 並行プログラミングのディスラプティブ技術としての Node.js について検討しています。
  • JavaScript フレームワークの比較」(Joe Lennon 著、developerWorks、2010年2月): この記事で比較よりも重要な内容は、JavaScript 開発を最大限に生かすセレクター、DOM トラバース、イベント処理などの機能についての詳しい説明です。
  • GWT の魅力: 第 1 回」(David Geary 著、developerWorks、2009年9月): GWT が Java コードを JavaScript にコンパイルすることによって、ブラウザーで実行するリッチなユーザー・インターフェースを実現する仕組みを学んでください。
  • Node.js とは一体何か?」(Michael Abernethy 著、developerWorks、2011年4月): Michael Abernethy 氏が Node の機能をわかりやすく概説するとともに、現在の制約事項を説明しています。
  • Node.js をクラウド開発環境のフルスタックとして使用する」(Noah Gift、Jeremy Jones 共著、developerWorks、2011年4月): コールバックによる非同期 I/O を使用する並行性モデルを採り入れて、チャット・サーバーを構築してください。
  • Java Technology bookstore で、この記事で取り上げた技術やその他の技術に関する本を探してください。
  • developerWorks Java technology ゾーン: Java プログラミングのあらゆる側面を網羅した記事が豊富に用意されています。

製品や技術を入手するために

  • Google Chrome のダウンロード: Web ページを使わずに JavaScript を扱う最善の方法の 1 つです。
  • Standard ECMA-262: ECMAScript の仕様です。
  • Node.js: Google の V8 JavaScript エンジンをベースに作成されたイベント駆動型 I/O フレームワークです。

議論するために

  • developerWorks コミュニティーに参加してください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者が主導するブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology, Open source
ArticleID=664897
ArticleTitle=Java 開発 2.0: Java 開発者のための JavaScript
publish-date=06032011