2006年06月21日

JavaScript

今更の感も強いが、これまで見様見真似でしか書いたことのなかったJavaScriptを勉強した。

教科書はO'reillyの JavaScript: The Definitive Guide, 4th Edition, David Flanagan。 日本語訳は第3版がJavaScript第3版として出ているが、第4版は出ていないようだ。

web上のJavaScriptの紹介にはHTML上の効果としての使い方しか載せていないもの、入門と銘打っていても言語の表層的なシンタックスしか解説していないものがほとんどで、言語として理解しようとすると物足りない。

一方、この本では前半分を使って言語としてのJavaScriptを丁寧に説明している。特に他のプログラミング言語の知識がある人には非常にわかりやすく、面白い。後半はJavaScriptの主な用途であるウェブブラウザでHTMLと組み合わせての使用のため、そこで登場するJavaScriptオブジェクトを説明するとともに、合わせて必要となるHTMLフォームやCSS、クッキー等の知識も要領よく解説している。

言語としてのJavaScriptは結構面白く、一読してもっと早くこの本を読んでおけばよかったと感じた。ただ、多くの項目でブラウザやJavaScriptのバージョンによって色々事情が異なるらしく、互換性についての記述が細かい。そのため言語を使おうとする側としては面倒な感を受けるが、多様なブラウザが使われている現状では致し方ないだろう。もっとも、記述があることは解説書としてそういった差異を丁寧にフォローしていると言える。

そのJavaScriptという言語であるが、JavaScriptは演算子や制御構文といった基本的なシンタックスはCやJavaに似ている。コメントの構文もC/Java譲り。 しかし、似ているのはそれだけ。言語としてはむしろScheme等に近く、そこにプロトタイプベースのオブジェクトを持ち込んだ感じである。

まず、変数には型がない。値は数値(整数と浮動小数点数の区別はなく、64bit浮動小数点数で全てまかなう)、ブーリアン、文字列、そしてオブジェクトのみ。文字列はimmutable。これらの間で必要に応じて暗黙の型変換があり、便利でもあるが嫌らしいような気もする。

クロージャがある(クロージャはオブジェクトの特殊なサブタイプとして扱われる)。 関数定義はクロージャの変数への束縛にすぎない。次の2つはほぼ同義。

function foo(x) { return x }
var foo = function(x) { return x }

括弧をつけてfoo(1)とすれば関数適用だが、fooと名前だけ書くと変数として参照する。

クロージャであるから当然次のようなコードも可能。

function make_counter() {
  var x=0
  return function() { return x++; }
}
var c = make_counter()
alert(c()) // 0を表示
alert(c()) // 1を表示

以上に加えて、オブジェクトがある。JavaScriptでいうところのオブジェクトは畢竟、文字列をキーとする連想配列だ。オブジェクトの要素をプロパティといい、通常obj.propとして参照するが、obj["prop"]としても参照できる。連想配列なので、他の言語のハッシュテーブルにも似た

var p = { x: 10, y: 20 }

というリテラル表現でも書けてしまう。

オブジェクトのメソッドは、単にプロパティにクロージャが代入されているものだ。

obj.method = function () { ... }

後ろに関数適用の括弧をつけてobj.method()とすればメソッド呼び出しとなる。 ただし、JavaScriptの関数ではthisという暗黙的に用意される参照があり、obj.method()という形式で呼ぶとその関数の中でthisがレシーバobjを指す。ちなみに通常の関数呼び出しでもthisはあり、グローバル環境の実行コンテクストを指す。

オブジェクトの作成はnew演算子をつけて関数を呼ぶことで行う。new Constructor()とすると、新しい空のオブジェクトが作成され、関数Constructorが呼ばれる。関数Constructorの中ではそれをthisとして参照できる。オブジェクトを作るための関数(これをコンストラクタと呼ぶ)は、この新しいオブジェクトに必要なプロパティやメソッドを与えることでオブジェクトを「作る」。例えばこんな具合。

function Point(x,y) { this.x = x; this.y = y }
var p = new Point(10,20)

JavaScriptにはクラスという概念はないが、あるコンストラクタが作成するオブジェクトに共通のプロパティを集めたオブジェクト(これをプロトタイプと呼ぶ)を持てる。オブジェクトは、プロトタイプが持つプロパティを自分自身が備えているかのように振舞う。

function Circle(r) { this.r = r }
    // コンストラクタのprototypeプロパティがプロトタイプを指す。
    // デフォルトではプロトタイプは空のオブジェクト。
    // そこにメソッドを追加する。
Circle.prototype.area = function() { return 3.141592 * this.r * this.r }
var c = new Circle(5)
alert(c.area()) // 78.5398と表示

他にもあるが、JavaScriptはどういう言語かというと概略こんな感じの言語である。

追記。JavaScript: The Definitive Guideは2006年8月に5th editionが出版される予定らしい。5年振りの改訂で、XMLやAjax関連の記述も加筆されるようだ。

この記事へのトラックバックURL
http://blog.seesaa.jp/tb/19591451
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
この記事へのコメント
短い例を引き合いに、JavaScript の面白いところを簡素に説明され、とても興味深く思いました。

ただ、(意図的かもしれませんが)例示してるコードの全ての行に ; (セミコロン)が不足しています。
Posted by ef at 2008年04月02日 13:23
efさん、コメントありがとうございます。拙文でJavaScriptに面白さを感じていただけたなら幸いです。

セミコロンについては説明を省いてしまいましたが、JavaScriptでは文の切れ目が行末などと重なる場合は省略できます。この点、CやJavaではセミコロンが必須であるのと異なっています。
Posted by 筆者 at 2008年04月03日 22:17
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。