JavaScriptに本格入門してみた

概要

現在、Webアプリやサービスの開発を行う為に、JavaScriptは重要な技術となっている様です。特に、Ajax技術*1は必須でしょう。

そんな訳で手始めに、以下の本にひと通り目を通しました。

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

この内容を自身の脳みそに定着させる為、本エントリでは、私が重要だと思ったポイントをまとめます。

参考:javascriptの関数が変態すぎる - 俺のメモ

javascriptを書き始める

流石に忘れないと思いますが、念のため。

<script type="text/javascript">
	//コードをここに
</script>

hoge.htmlファイル中に埋め込む場合はこれです。

<script type="text/javascript" src="sample.js"></script>

sample.jsを外部に置き、hoge.htmlから読み込む場合はこれです。sample.jsファイルには、直接javascriptのコードを書いて大丈夫です。

ちなみにscriptタグは、headタグの配下、もしくはbodyの終了タグ(/body)直前に書くのが一般的だそうです。

変数の扱い

定義

JavaScriptは、変数のデータ型に寛容です。ただし、配列、オブジェクト、関数に関しては参照型となる事に注意が必要です。
(今の一文に違和感を覚えた方。そうです。JavaScriptでは関数も一つのデータ型として扱います、がそれは次の節で)

変数宣言は以下の通りです。

var hogehoge;

varは省略可能なのですが、きっとそれは気のせいです。忘れましょう。省略すると、次の副節で示す弊害が発生します。

スコープ

一般的なプログラム言語同様、基本的に各変数は、定義された関数内でのみ有効です。

但し例外があり、varを省略した変数は、グローバルとして扱われます。例えば以下の場合、最初に定義したhogehogeが書き換えられます。

hogehoge = 'hogeString';

function testScope(){
	hogehoge = 'hogeLocalString';
}

関数の扱い

静的定義

特に難しい事はありません。任意の場所にfunction命令で定義します。

function average(arg, arg2){
	return (arg + arg2)/2;
}
関数リテラルとして定義

この辺りからJavaScriptの自由っぷりが見られます。

var ave = function(arg, arg2){
	return (arg + arg2)/2;		
};

JavaScriptでは、関数をあたかも変数であるかの様に代入できます。この時、関数その物には名前が有りません。この様な関数を、匿名関数と呼びます。

Functionコンストラクタで定義

更に自由になるJavaScriptさん。
関数定義の三番目の方法として、Functionコンストラクタがあります。これを利用すると、こんな芸当もできます。

var param = 'arg, arg2';
var formula = 'return (arg + arg2)/2;';
var ave = new Function(param, formula);

但しこれは処理が重く、また記述も煩雑となるので、基本的には封印しておきましょう。

また、関数内においてこの方法で定義した場合、グローバル変数を優先して参照します。

var hoge = 'Global';	//new Functionで有効

function testScope(){
	var hoge = 'Local';	//function()で有効
	
	var fCon = new Function('return hoge;');
	var fLit = function(){return hoge;};
}

これが仕様とは言え、不可解な挙動に変わりはないので、やっぱりnewは封印しましょう。

可変長引数の利用

実はJavaScriptでは、呼び出し時の引数の個数を確認していません。これら引数は全て、argumentsオブジェクトから読み出せます。

function variableArg(req_arg, var_args){
	for(var i = 1; i < arguments.length; i++){
		req_arg += '・' + arguments[i];
	}
	
	return req_arg;
}

var myName = variableArg('ジョン', '中澤', 'ゴンザレス', '英寿');
クロージャの利用

クロージャは、ある関数のローカル変数を参照する関数であり、簡易的なクラスの様に働きます。

function closure(init){
	var i = init;
	
	return function(){
		return --i;
	}
}
	
var closureFunc = closure(100);
var closureFunc2 = closure(50);

window.alert(closureFunc()); //結果は99
window.alert(closureFunc2()); //結果は49
	
window.alert(closureFunc()); //結果は98
window.alert(closureFunc2()); //結果は48	

直感的には分かり難いかも知れませんが、クロージャの関数リテラルを生成する度にローカル変数領域は新たに作られます。
その為この例の様に、一つ目のクロージャと二つめのクロージャは独立に動作します。

オブジェクト指向的実装

コンストラクタとプロトタイプによるオブジェクトの定義

通常、メンバ変数に相当する物はthisキーワードを付けてコンストラクタで、メソッドに相当する物はprototypeオブジェクトに対して定義します。
百聞は一見にしかず。

var Item = function(name, price, stock){
	this.name = name;
	this.price = price;
	this.stock = stock;
};

Item.prototype.getTotalValue = function(){
	return this.price * this.stock;
};
	
var item = new Item('水','200','100')
window.alert(item.getTotalValue());

またprototypeに対する定義が複数ある場合、以下の様にまとめる事ができます。

var Hoge = function(){};
Hoge.frototype = {
	hage : function(){ ... ;},
	hige : function(){ ... ;},
	huge : function(){ ... ;}
};
プロトタイプチェーンによるオブジェクトの継承

javascriptでは、派生クラスのプロトタイプに基底クラスのインスタンスを持たせる事で、継承を実現します。

var Vehicle = function(){};
Vehicle.prototype.move = function(){ window.alert('動く') ;};

var Boat = function(){};
Boat.prototype = new Vehicle();
Boat.prototype.float = function(){window.alert('浮く');};

var boat = new Boat();
boat.move();
boat.float();

これらメソッドの呼び出し動作は、まず自インスタンスを検索し、次にプロトタイプを検索。それでも見つから無ければプロトタイプの持つクラスのインスタンスを検索、そして更にそのプロトタイプを検索...。と連鎖していきます。この仕組みの為に、プロトタイプチェーンという名前が付いているのでしょう。

静的プロパティと静的メソッドの定義

静的要素は、定義したオブジェクトその物に追加していきます。

var MyMath = function(){};

MyMath.pi = 3;

MyMath.circleArea = funciton(rad){
	return rad*rad*3;
}

javascriptからブラウザ、ドキュメントを操作する

冒頭に挙げた本では、javascriptの文法に続いて、ウィンドウ操作やドキュメントの操作について解説されます。ここではそれは割愛しますので、その辺りが知りたい方は本を直接ご覧になるか、関連するWeb上の情報をあたって下さい。但し以下に、ドキュメントとjavascriptを接続する方法についてのみ、まとめます。

javascriptによるイベント処理

ドキュメントに対して何らかの操作があったとき、それをjavascriptで処理する為には、イベントリスナを利用します。但しこの仕組み、各社のブラウザによって挙動が違うという、中々面倒な仕様です。javascriptで素書きする事も可能ですが、通常はライブラリの力を借ります。例えば、jQueryを利用した場合は以下の様にできます。

$('#btn').click(//ボタンクリック時の処理を定義
	function () {
		window.alert('ボタンがクリックされました');
	}
);

この時htmlには、jQueryの読み込み命令とid='btn'のbuttonが既にあるとします。

<script type="text/javascript" src="jquery.js"></script>
<input type="button" id='btn' value="ボタン" />

以上の要素を組み合わせる事で、「#btnをクリックしたときにwindow.alertメソッドを呼ぶ」、というイベントが登録できます。
但し注意が必要で、このイベントを登録するという動作そのものは、ページ全体のロード後に実行しなければなりません。これは、イベントリスナ登録を行う時点で、それが登録されるオブジェクトの読み込みが終了していなければならない為です。よってこの場合の対処法は二つ有り、一つはイベント登録をinputタグより後に書くこと。もう一つは、以下の様にjQueryの機能を利用してページロード後に、イベント登録が行われる様にする事です。通常は、後者を利用する事になります。

$(
	function () {
		$('#btn').click(function () { //処理... ;} );
	}
);

尚、jQueryそのものの仕様については、以下のページが参考になりそうです。
入門:はじめてのjQuery
辞典:jQuery 日本語リファレンス

jQueryを使ったajax通信

javascriptを使う最大の理由と言っても良いajax。これもjQueryを利用する事で、比較的簡単に記述できます。

function () {
	//通信開始前にメッセージを表示
	$('result').html('通信中...');

	//Ajax通信を開始
	$.ajax({
		//通信内容設定
		url: 'hogehoge.php',
		type: 'GET',
		dataType: 'json',
		data: $('form').serializeArray(),
		timeout: 5000,

		//通信成功時の処理
		success: function (data) {
		},

		//通信失敗時の処理
		error: function () {
		}
	});
}

この時忘れてはいけないのは、プログラム側で、通信中である事を明示する事です。
もちろん、それが無くても動作はします。ですが、ajaxでは通信にページの遷移を伴わない為、ユーザには何が起きているのか分かりません。ユーザビリティの為にajaxを導入するのですから、こういう細いケアも怠らない様にしましょう。

まとめ

このエントリでは、javascriptの基礎から、jQueryを使ったイベントの登録、ajax通信の雛形までをざっくりとまとめました。
以上で一応はクライアントサイド技術への取っ掛かりができましたので、次はサーバサイド技術の俯瞰を目指したいと思います。