HTML とは
HTML とは、誤解を恐れずに言ってしまうとウェブページ(ホームページ)を作るために使われている言語です。 例えば、以下のようなものが HTML です。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<title>タイトル</title>
</head>
<body>
<h1>見出し</h1>
<p>
本文本文本文本文本文本文本文本文本文本文本文本文本文本文
本文本文<a href="hoge.html">ハイパーリンク</a>本文
本文本文本文本文本文本文本文本文本文本文本文本文本文本文
</p>
</body>
</html>
イメージ湧きましたか?
では、何故 HTML というものが必要なのでしょうか。 言い方を変えると「シンプルテキストとの違いは?」なんなのでしょうか。 それは、二つあります。
- ハイパーリンクを張ることができる
- 文章を構造化することができる
ハイパーリンクとは
ハイパーリンクとはこういったテキストのこと、つまり単語をポチっと押して別の文章に飛ぶ仕組みです。
ハイパーテキスト以前の文章では、関連する事柄を知りたいときに、 その文章に付属する参考文献の章などを調べなければいけませんでした。 それがあたりまえだったのです。 ハイパーリンクはとてつもなく画期的な仕組みだったのです。
また、文章中にハイパーリンクを含んだ文章を、ハイパーテキストといいます。 HyperText Markup Language というのは、元々そういう意味だったんですね。
以下に、ハイパーリンクを張っている HTML の例を示します。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"><html lang="ja"><head><title>タイトル</title></head><body>
<p>
<a href="programming.html">プログラミング</a>ってどんなことだと思いますか?
一番想像しやすい例をあげると、「ゲームを作る作業」は
<a href="programming.html">プログラミング</a>ですよね。
そんなイメージありませんか?
僕も、最初に「<a href="programming.html">プログラミング</a>ってどんなこと?」で想像したのは
「ゲームとか<a href="excel.html">エクセル</a>みたいなのを作ること!」でした。
</p>
</body></html>
簡単ですね!
文章を構造化するとは
文章を構造化するとは、段落や見出しなどの「テキストの文章内における役割」を文章中に持たせることです。
たとえば、以下のような文章があったとします。
** 今日買ったもの **
今日買ったものは、以下の通りです。
- りんご
- みかん
- にんじん
もし、この文章を見たのが人間ならば、どこが見出しで、どこが段落で、どこが箇条書きかなどの文章の構造が分かると思います。 しかし、それは機械からは分かりません。
インターネット上に置いた文章は、人間だけが読むものではありません。 検索エンジンなど、様々なプログラムがインターネット上に置いた文章を読む可能性があります。
では、この文章を HTML を使って構造化してみましょう。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<title>今日買ったもの</title>
</head>
<body>
<h1>今日買ったもの</h1>
<p>
今日買ったものは、以下の通りです。
</p>
<ul>
<li>りんご</li>
<li>みかん</li>
<li>にんじん</li>
</ul>
</body>
</html>
簡単ですね!
JavaScript とは
JavaScript とは、「HTML に動きを付けるためのプログラミング言語」です。 今では Opera, Firefox, Safari, IE で JavaScript (または、 JavaScript 互換)の言語を使うことができます。
JavaScript は、 script 要素の中(<script type="text/javascript"> と </script>の間)に記述します。 特に head 要素の中に書く必要はありませんが、慣例的に head 要素の中に書かれることが多いです。
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>JavaScript で "Hello, world!"</title>
<script type="text/javascript">
alert('Hello, world!');
</script>
</head>
<body><p>JavaScript で "Hello, world!"</p></body>
</html>
動きましたか? alert( ... ) の中に書いた値が表示されたんですね! なんとなく分かった感じになってください!
JavaScript ダイジェスト
この章は他のプログラミング言語にある程度触ったことのある人向けの JavaScript の概要の解説です。 もし、プログラミング言語の経験があまり無い人は、次の章の JavaScript チュートリアルから始めましょう。
JavaScript ってどんな言語?
JavaScript って、他の言語と比べると以下のような特徴があります。
- メモリを直接意識しない言語
- 変数に型がなく、暗黙的に型変換が行われる言語
- 無名関数を多用する言語
- 柔軟なデータ構造を扱える言語
メモリを直接意識しない言語
JavaScript は、メモリのアドレスを扱うようなことは一切ありません。
// 変数 a にメモリのアドレスが代入される訳ではない
var a = "hoge";
// メモリのアドレスを比較している訳ではない
if (a === "hoge") {
alert('ok');
}
変数に型がなく、暗黙的に型変換が行われる言語
JavaScript は、値に型はありますが、変数に型がありません。
変数には全ての型の値が代入可能
var a; // 同じ変数に
a = "hoge"; // 文字列型の値
a = 1; // 数値型の値
a = true; // 論理型の値
a = undefined; // Undefined 型の値
a = null; // Null 型の値
a = { a: 1 }; // オブジェクト型の値
a = [1, 2]; // 配列(オブジェクト型の値)
a = function() { alert(1) }; // 関数(オブジェクト型の値)
alert('ok'); // を代入しても、エラーにならない
演算子が暗黙的に型変換を行う
演算子は、何型が来たら何型に変換するというルール持ってます。
alert(+"3"); // 単項演算子 + の型変換ルールで、数値型に変換される
alert(!""); // 単項演算子 ! の型変換ルールで、論理型に変換される
alert(true * "3"); // 二項演算子 * の型変換ルールで、数値型に変換される
alert("hoge"[0]); // 二項演算子 [] の型変換ルールで、左辺はオブジェクト型に、右辺は文字列型に変換される
少し複雑な型変換
少し複雑な型変換ルールを持つ演算子もあります。
// 二項演算子 + の型変換ルール
alert("hoge" + 1); // 右辺左辺どちらかが文字列型の場合、両辺文字列型に変換する
alert(null + true); // 右辺左辺どちらかが文字列型でない場合、両辺数値型に変換する
// 二項演算子 || の型変換ルール
// 左辺を論理型に変換し、 true ならば変換前の左辺を、 false なら右辺を返す
alert("hoge" || true);
alert("" || 0);
具体的な型変換後の値一覧
- 数値型
- → 文字列型(-1 だったら "-1" 、3 だったら "3" というような感じ)
- → 論理型(0 以外 true, 0 は false)
- → オブジェクト型(Number オブジェクト)
- 文字列型
- → 数値型("3" や "-1" のように数値と解釈できるものは、その数値に変換される。その他は NaN に変換される)
- → 論理型("" 以外 true, "" は false)
- → オブジェクト型(String オブジェクト)
- 論理型
- → 数値型(true は 1, false は 0)
- → 文字列型(true は "true", false は "false")
- → オブジェクト型(Boolean オブジェクト)
- オブジェクト型
- → 論理型(true)
- → 数値型(valueOf 無ければ toString が呼び出される)
- → 文字列型(toString 無ければ valueOf が呼び出される)
- Null 型
- → 論理型(false)
- → 数値型(0)
- → 文字列型("null")
- → オブジェクト型(エラーが発生する)
- Undefined 型
- → 論理型(false)
- → 数値型(NaN)
- → 文字列型("undefined")
- → オブジェクト型(エラーが発生する)
無名関数を多用する言語
JavaScript は他の様々な言語と比べて非常によく、無名の関数を使う言語です。
値としての関数
JavaScript では関数を値として扱うことができます。
// 変数に代入可能
var hoge = function(a) {
alert(a);
};
// function hoge() { ... }
// と書くのとほぼ等価
hoge(3);
// 関数を受け取る関数
function each(array, fn) {
var result = [];
for (var i = 0; i < array.length; i ++)
result[i] = fn(array[i]);
return result;
}
var array = each([0, 1, 2], function(a) { return a + 1 });
alert(array);
// 関数を返す関数
function K(val) {
return function() { return val };
}
var one = K(1);
alert(one());
alert(one());
function add(a) {
return function (b) { return a + b };
}
alert(add(3)(4));
変数のスコープ
JavaScript の変数のスコープは、レキシカルな関数スコープです。
// 内側から外側の変数を使える
var a = 'global', b = 'global', c = 'global';
function hoge() {
var b = 'hoge', c = 'hoge';
function fuga() {
var c = 'fuga';
alert(a); alert(b); alert(c);
}
fuga();
}
hoge();
関数生成時の変数保存
例えば、以下のはどうなるでしょう
var num;
function hoge() {
var i = num;
return function() { return i };
}
num = 0;
var a = hoge();
num = 1;
var b = hoge();
alert(a()); // 0 or 1 ??
alert(a === b); // true or false ??
関数内の環境は実行ごとに作られ、そして、関数は生成時の環境を保存しています。
柔軟なデータ構造を扱える言語
JavaScript では、複雑なデータを扱うときにオブジェクトというものを使います。 オブジェクトは、一般的にハッシュや連想配列というものと同じものです。
var obj = {
hoge: 1,
fuga: 2,
'hoge-hoge': 3
};
alert(obj['hoge']);
alert(obj['fuga']);
alert(obj['piyo']);
alert(obj['hoge-hoge']);
このオブジェクトの値を格納するモノのことをプロパティといいます。 そして、 [ ] のことをプロパティアクセス演算子といいます。
ドットを使う
プロパティアクセス演算子の代わりに、ドットを使うことができます。
var obj = {
hoge: 1,
fuga: 2,
'hoge-hoge': 3
};
alert(obj.hoge);
alert(obj.fuga);
alert(obj.piyo);
alert(obj['hoge-hoge']); // このような名前の場合はドットが使えない
obj['piyo'] = 4;
alert(obj['piyo']);
ドットを使う
プロパティアクセス演算子の代わりに、ドットを使うことができます。
var obj = {
hoge: 1,
fuga: 2,
'hoge-hoge': 3
};
alert(obj.hoge);
alert(obj.fuga);
alert(obj.piyo);
alert(obj['hoge-hoge']); // このような名前の場合はドットが使えない
obj.piyo = 4;
alert(obj.piyo);
関数をプロパティに入れる
関数ももちろんプロパティに代入することができます。
var obj = {
hoge: 1,
// this というキーワードを使うと
fuga: function() {
alert(this.hoge);
}
};
// 呼び出し時に obj が this に割り当てられる
obj.fuga();
var piyo = obj.fuga;
piyo(); // 1 ??
this はプロパティアクセス演算子と関数呼び出しの組み合わせで与えられます。
new 演算子でオブジェクトを作る
new 演算子を関数に使って、オブジェクトを作ることができます。
var obj = new function() {};
obj.hoge = 1;
alert(obj.hoge);
new 演算子を使うとより直感的にオブジェクトを生成することが出来ます。
// 犬コンストラクタ
function Dog(name) {
this.name = name;
this.saysName = function() {
alert(this.name);
};
};
var pochi = new Dog('ポチ');
pochi.saysName();
オブジェクトを作るための関数をコンストラクタと呼んだりします。
複数のオブジェクトの性質を持つオブジェクト
JavaScript のオブジェクトが普通のハッシュや連想配列と決定的に違うのは、 複数のオブジェクトのプロパティをミックスできることです。
var base = {
hoge: 1,
fuga: 2
};
function Hoge() {
this.fuga = 3;
this.piyo = 4;
}
Hoge.prototype = base;
var obj = new Hoge;
alert(obj.hoge);
alert(obj.fuga);
alert(obj.piyo);
この obj にとっての base をプロトタイプオブジェクトといいます。
// 犬コンストラクタ
function Dog(name) {
this.name = name;
};
Dog.prototype = {
saysName: function() {
alert(this.name);
}
};
var pochi = new Dog('ポチ');
pochi.saysName();
配列もオブジェクト
実は、配列もオブジェクトです。
// 配列はオブジェクト
var array = ['a', 'b', 'c'];
// 以下のようなオブジェクトを作るのとほぼ等価
// var array = {
// length : 3,
// 0: 'a',
// 1: 'b',
// 2: 'c'
// }
// 参照はプロパティアクセスに過ぎない
alert(array[0]);
alert(array['0']);
また、配列は Array.prototype をプロトタイプとしています。
// 最初の要素を取得する
Array.prototype.first = function() {
return this[0];
};
alert([1, 2, 3].first());
JavaScript チュートリアル
プログラミングの経験があまりない人は、簡単な例から少しずつ JavaScript にチャレンジしてみましょう。
alert で色々な値を表示してみよう!
JavaScript には様々な種類の値があります。 様々な値を alert に放り込んでみましょう。
alert('Hello, world!');
alert("Hello, world!");
alert(1);
alert(true);
alert(false);
alert(null);
alert(undefined);
alert({ 'a': 1, 'b': 2 });
alert([1, 2, 3]);
alert(function() {});
動きましたか?簡単ですね!
このように、 JavaScript の値には様々な種類があります。 この種類のことを値の型または、データ型といいます。 JavaScript の型は以下の種類があります。
- プリミティブ型
- 数値型(1, -1, 0.3, 3e+4, NaN, Infinity など)
- 文字列型('Hello, world!', "foo" など)
- 論理値(true, false)
- null 型(null)
- undefined 型(undefined)
- オブジェクト型({ 'a': 1, 'b': 2}, [1, 2, 3], function() {} など)
また、例を動かしてみて分かったと思いますが、一行一行が順に実行されて行きますね。 この順に実行されて行く手続きの一つ一つを文といいます。
値というのは非常に曖昧な言葉なので、この文章では値を厳密に以下のようなものと定義したいと思います。
- 値は、変数に代入可能
- 値は、引数として関数に渡せる
- 値は、返り値として返せる
変数を使ってみよう!
変数を宣言して、変数に値を代入することで、以降、変数をその値として扱うことができるようになります。 以下の例を実行してみましょう。
var a; // a という変数を宣言します
alert(a); // a に代入された値(初期値は undefined)を表示します
a = 1; // a に 1 という値を代入します
alert(a);
a = 'hoge';
alert(a);
var b = a;
alert(b);
動きましたか? 変数は var 文で宣言し、変数への値の代入は = で行います。
そんなに難しくはないですね!
C 言語をやったことのある人は、「変数に型がない」ということにも注目しましょう。
計算してみよう!
次は、足し算や引き算をしてみましょう!
var a = 2;
var b = 3;
var c = a + b;
var d = c - 4;
alert(d);
動きましたか?簡単ですね!
また、この 2 や 3 や a + b や c - 4 や d などの、 文中の値として扱える部分のことを式といいます。
足し算や引き算は、左辺右辺も式を取るので、入れ子にして書くことができます。

alert(3 + (5 - 3) - 4);
// 式: 5 - 3 は 2 という値として扱える
// 式: (5 - 3) は 2 という値として扱える
// 式: 3 + (5 - 3) は 5 という値として扱える
// 式: 3 + (5 - 3) - 4 は 1 という値として扱える
「何が式」で、「どこに式が書けるか」を考えていくことがプログラミング上達の肝です。 ここは、重要なので頑張って理解しましょう。
また、足し算引き算以外にも様々な計算があります。
var a = 1;
a ++; // a の値を 1 加算する a = a + 1 と等価
a --; // a の値を 1 減算する a = a - 1 と等価
alert(a);
alert(1 * 3); // かけ算
alert(9 / 3); // 割り算
数値以外の計算もしてみよう!
数値以外の計算もしてみましょう!
// 論理演算
alert(true && true);
alert(true && false);
alert(false && false);
alert(true || true);
alert(true || false);
alert(false || false);
// 文字列の結合
alert("hoge" + "fuga");
型変換を理解しよう!
JavaScript では計算の際に、データ型の変換が行われることがあります。 以下の例を実行して理解してみましょう!
// 文字列 → 数値
alert(10 - "3");
alert(10 - "3hoge");
// 数値 → 文字列
alert('hoge' + 3);
// 数値 → 論理値 (計算の過程で、 1 が true に変換されるが、式の値は 1 になる)
alert(1 || 'hoge');
値が、型変換されたときに何になるかということを意識できると柔軟なプログラミングが可能になります。 代表的な方変換のルールをまとめておきます。
- 数値型
- → 文字列型(-1 だったら "-1" 、3 だったら "3" というような感じ)
- → 論理型(0 以外 true, 0 は false)
- → オブジェクト型(Number オブジェクト)
- 文字列型
- → 数値型("3" や "-1" のように数値と解釈できるものは、その数値に変換される。その他は NaN に変換される)
- → 論理型("" 以外 true, "" は false)
- → オブジェクト型(String オブジェクト)
- 論理型
- → 数値型(true は 1, false は 0)
- → 文字列型(true は "true", false は "false")
- → オブジェクト型(Boolean オブジェクト)
- オブジェクト型
- → 論理型(true)
- → 数値型(valueOf 無ければ toString が呼び出される)
- → 文字列型(toString 無ければ valueOf が呼び出される)
- Null 型
- → 論理型(false)
- → 数値型(0)
- → 文字列型("null")
- → オブジェクト型(エラーが発生する)
- Undefined 型
- → 論理型(false)
- → 数値型(NaN)
- → 文字列型("undefined")
- → オブジェクト型(エラーが発生する)
制御文を使おう
文は上から順に一回ずつ実行されます。 しかし、それでは単純なプログラムしか作ることができません。 ということで、様々な制御文が用意されています。
制御文とは「こうだったら、これをする」とか、「この条件のうちはこれを繰り返す」というようなことをするための文です。
var a = true;
var b = 4;
while (b--) { // ( ) 内の式を評価し、論理型に型変換して true の間次に続く文を繰り返す。
if (a) { // ( ) 内の式を評価し、論理型に型変換して true なら次に続く文を実行する。
alert(1);
a = false;
}
else { // 直前の if 文が実行されない場合ここが実行される
alert(2);
a = true;
}
}
また、 for 文という少し複雑な制御文もあります。
for (var i = 0; i < 4; i ++) {
alert(i);
}
// これは
// var i = 0;
// while(i < 4) {
// alert(i);
// i ++;
// }
// と等しい
関数を使ってみよう!
prompt 関数というものを使って、ユーザの入力を取って足し算をしてみましょう!
ユーザの入力は、文字列のデータとして返ってくるので、 さらに parseInt 関数で文字列を数値に変換する必要があります。
var a = prompt('数値を入力してください');
var b = prompt('数値を入力してください');
a = parseInt(a);
b = parseInt(b);
var c = a + b;
alert(c);
動きましたか? ここで、少し関数について説明します。
関数とは、様々な手続き(文)を保存したものです。 今まで、登場した関数は以下の三つです。
- alert
- prompt
- parseInt
「関数名(式, 式, ...)」と書くことで、関数に保存された手続き(文)を実行することができます。 このことを関数を呼び出すと言います。
関数は呼び出すときに丸カッコの中に 0 個以上の式を書くことができます。(この式によって生成され、関数に渡される値を引数といいます) そして、呼び出した結果、値を返します。(この関数によって返される値を返り値といいます。) さっきの例では、 parseInt によって文字列を数値化した値が返されたのです。
この関数の呼び出しもまた式です。 ですので、値そのものとして扱うことができます。
alert(parseInt(prompt('数値を入力してください')) + parseInt(prompt('数値を入力してください')));
どうですか?理解できるでしょうか? 頑張ってください(><)ノ
関数を作ってみよう(1)
次は、関数を自分で作ってみましょう。関数は以下のように書きます。
function calc(a, b, c) {
var d = a + b;
return d * c;
}
alert(calc(3, 2, parseInt(prompt('number?'))));
動きましたか?簡単ですね!
関数を作ってみよう(2)
さっきと同じ関数を違う方法で作ってみます。 この例の挙動は、さっきの例と全く同じです。
var calc = function(a, b, c) {
var d = a + b;
return d * c;
};
alert(calc(3, 2, parseInt(prompt('number?'))));
動きましたか?
このように JavaScript では関数も値です。
少し難しいですが、とても重要な概念です。 さっきの例が、この例と同じであるということを頭に叩き込みましょう!
もう一度、関数を考えてみよう
JavaScript では関数は値だといいました。 実は、今までに出てきた alert や prompt や parseInt と言った関数も、ただ単に関数という値の入った変数に過ぎなかったのです!
var hoge = alert;
hoge('Hello, world!');
もう少し、見てみましょう
function hoge() {
return alert;
}
hoge()('Hello, world!')
もっと、見てみましょう
(function(fn) {
return fn;
})(alert)('Hello, world!');
どうですか? ちょっと難しいですが、関数呼び出しの () と関数が別れて見えてきましたか?
関数呼び出しが、「式(式, 式, ...)」に見えてくれば完璧です。
変数の有効な範囲
JavaScript は関数スコープを採用しています。
function hoge() {
var a = 'local'; // この a はこの関数内だけで有効
alert(a);
alert(b);
}
var a = 'global';
var b = 'global';
hoge();
alert(a);
alert(b);
関数の中で関数を作ってみよう!
JavaScript では関数の中で関数を作ることができます。
function hoge() {
var a = 0;
function fuga() {
a = a + 2;
}
fuga();
fuga();
alert(a);
}
hoge();
// fuga は hoge の外からは呼び出せない。
// fuga();
このとき、内側の関数から外側にある関数の変数が見えていることに注意しましょう。
関数を返す関数を作ってみよう!
JavaScript では関数も値なので、 return で返すことができます。
function K(v) {
return function() {
return v;
};
}
var f = K(0);
var g = K(1);
alert(f());
alert(f());
alert(g());
alert(g());
最初は、何に役に立つのか分からないかもしれませんがとても役に立ちます。
関数を受け取る関数を作ってみよう!
関数を受け取る関数もテクニックとして使うことがあります。
function arg1(f) {
return f(1);
}
arg1(alert);
alert(arg1(function(b) {
return b + 1;
}));
これも、最初は何に役に立つのか分からないかもしれませんがとても役に立ちます。
オブジェクトを使ってみよう!
オブジェクトとは、複数の値を持った値です。 他のプログラミング言語の連想配列と同じものです。
var obj = {
a: 1,
b: 2
};
alert(obj.a);
alert(obj.b);
alert(obj['a']);
alert(obj['b']);
alert(obj.c);
obj.c = 3;
alert(obj.c);
オブジェクトの値を格納する名前のことをプロパティといいます。
オブジェクトには、関数を格納することができます。 プロパティに入っている関数を呼び出した場合、 関数内の this というキーワードにそのオブジェクトが割り当てられて呼び出されます。
var obj = {
a: 1,
b: function() {
alert(this.a);
}
};
alert(obj.b);
obj.b(); // このとき obj.b 内の this に obj が割り当てられる
関数からオブジェクトを作ってみよう!
また、関数に対して new という演算子を使うとオブジェクトを作ることができます。
var obj = new function() {
this.a = 1;
this.b = 2;
};
alert(obj.a);
alert(obj.b);
new でオブジェクトを作る場合は、関数内の this に新しく生成されたオブジェクトが割り当てられた状態で関数が実行されます。
function Hoge() {
this.a = Math.random(); // Math.random はランダムな値を求める関数
this.b = 2;
};
var obj0 = new Hoge;
alert(obj0.a);
var obj1 = new Hoge;
alert(obj1.a);
new するときに引数のように値を渡すことも出来ます。
function Hoge(a, b) {
this.a = a;
this.b = b;
};
var obj = new Hoge(1, 2);
alert(obj.a);
alert(obj.b);
オブジェクトの共通のプロパティを定義しよう!
関数の prototype プロパティに設定されているオブジェクトにプロパティを追加すると、 その関数から new で生成されたオブジェクトがすべてそのプロパティを持つようになります。
function Hoge(a, b) {
this.a = a;
this.b = b;
};
var obj0 = new Hoge(1, 2);
var obj1 = new Hoge(3, 4);
alert(obj0.c);
alert(obj1.c);
Hoge.prototype.c = 5;
alert(obj0.c);
alert(obj1.c);
配列を作ってみよう!
JavaScript の配列は [ ... ] を使って定義します。
var array = [1, 2, 3];
alert(array.length);
alert(array[0]);
alert(array[1]);
alert(array[2]);
// array[0] は以下のようにプロパティがアクセスされているに過ぎない。
alert(array['0']);
JavaScript の配列は実は、数値のプロパティを持ったただのオブジェクトに過ぎません。
var array = {
length: 3,
0: 1,
1, 2,
2, 3
};
alert(array.length);
alert(array[0]);
alert(array[1]);
alert(array[2]);
// array[0] は以下のようにプロパティがアクセスされているに過ぎない。
alert(array['0']);
ただ、他のオブジェクトと唯一違う点は、プロパティが更新されると length の値が自動で書き変わることです。
var array = [1, 2, 3];
alert(array.length);
array[1000] = 1;
alert(array.length);
配列を操作するための関数を使ってみよう!
配列オブジェクトのプロパティには、配列を操作するための様々な関数が用意されています。
var array = [1, 2, 3, 4, 5];
alert(array);
array.push(6); // 配列の最後に値を追加する
alert(array);
var val = array.pop(); // 配列の最後の値を取り出す
alert(val);
alert(array);
array.unshift(0); // 配列の最初に値を挿入する
alert(array);
val = array.shift(); // 配列の最初の値を取り出す
alert(val);
alert(array);
val = array.splice(1, 2); // 1 番目 2 番目の値を取り出して結果を配列にして返す。
alert(val);
alert(array);
配列に関数を追加してみよう!
実は [ ... ] というのは、以下の new Array; の省略記法にすぎません。
var array = new Array;
array[0] = 1;
array[1] = 2;
array[2] = 3;
alert(array.length);
ということは、 Array.prototype にプロパティを追加することですべての配列に共通の値を追加できるということです。
Array.prototype.first = function() {
return this[0];
};
alert([1, 2, 3].first());
alert([4, 5, 6].first());
以下に配列のすべての値を引数にして関数を呼び出す例を示します。
Array.prototype.each = function(fn) {
var result = [];
for (var i = 0; i < this.length; i ++) {
result.push(fn(this[i]));
}
return result;
};
alert([1, 2, 3].each(function(v) {
return v + 1;
}));
関数の引数をもっと柔軟に扱ってみよう!
関数の引数の数はほとんど決まっていますが、様々な個数の引数に対応したいことがあります。 そのような場合は、 arguments というオブジェクトを使います。
以下の例を見てください。
function hoge() {
alert(arguments[0]);
alert(arguments[1]);
alert(arguments.length);
}
hoge(1);
hoge(1, 2, 3);
arguments に入っているオブジェクトは、引数が配列のように数値のプロパティに格納されています。 ただし、 arguments オブジェクトは配列ではないので、配列に入っている関数は使うことができません。
関数の this をもっと理解しよう!
さきほどから出てきている関数の this は関数の実行時に割り当てられます。 つまり、 this は隠された第三の引数のようなものなのです。
関数には、明示的に this を渡す方法が用意されています。それが call と apply です。
ここでは、 apply を使って this を渡してみましょう。
function hoge(a, b, c) {
alert(this);
alert(a + b + c);
}
hoge.apply(1, [1, 2, 3]);
もうちょっと便利な例を見てみましょう。
alert([].pop.apply({
length: 2,
0: 'hoge',
1: 'fuga'
}));
配列の pop 関数を配列ではないオブジェクトに対して実行しています。
DOM つまみ食い
ここまでは JavaScript の文法ばかりをやってきました。 ここからは JavaScript で HTML をいじる方法を軽く解説したいと思います。
JavaScript には、DOM という HTML や XML の情報をいじるための API が実装されています。
DOM の概要を知ろう!
DOM をもう少し詳しく言うと Document Object Model の略で、 文章をどのようにオブジェクトとして表現するかという仕様群です。
DOM を使うことによって文章全体を木構造のオブジェクトとして扱うことができます。
たとえば、以下のような HTML の文章があるとします。
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>タイトル</title>
</head>
<body>
<h1>見出し</h1>
<ul>
<li>はくさい</li>
<li>しいたけ</li>
<li>にーんじん</li>
</ul>
</body>
</html>
ブラウザがこの HTML 文章を読み込むと、以下のような木構造のオブジェクト群が出来上がります。 (実際は、 HTML 中の空白もテキストノードとして生成されますが、ここでは可読性のため省略します。)
- document
- html 要素
- head 要素
- meta 要素
- title 要素
- "タイトル" テキストノード
- body 要素
- h1 要素
- "見出し" テキストノード
- ul 要素
- li 要素
- "はくさい" テキストノード
- li 要素
- "しいたけ" テキストノード
- li 要素
- "にーんじん" テキストノード
この木構造に繋がったオブジェクトのことを DOM ノードといい、木構造全体のことを DOM ツリーといいます。 一般的に良く使われる DOM ノードは以下の三つです。
- ドキュメント
- 要素
- テキストノード
DOM の操作の基本は、これらの DOM ノードを追加削除したり、 DOM ノードのプロパティを参照したり書き換えたりすることになります。
DOM を使う準備をしよう!
DOM は script 要素内に JavaScript を書いただけでは、ちゃんと使うことができません。 ブラウザが HTML を読み込んだときに、以下の手順で JavaScript が実行されているからです。
- HTML を読み込み上から順に DOM ツリーを構築していく
- script 要素を DOM ツリーに繋ぐ
- script 要素内の JavaScript を実行する
- 残りの DOM ツリーを構築して行く
つまり JavaScript が実行されている時点では中途半端な DOM ツリーしか出来ていないのです。
これでは、困ってしまいます。
これを解決するために、本講義では load イベントという仕組みを使います。 (本当は、 DOMContentLoaded などのイベントもあるが、ブラウザの互換性の面から今回は使わない)
具体的には、以下のようにして load イベントというものを使います。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Sample</title>
<script type="text/javascript">
alert('loading');
function main() {
// ここは DOM ツリーが構築された後に呼び出される。
alert('loaded!!');
}
</script>
</head>
<!-- body 要素の onload 属性に JavaScript を書く -->
<body onload="main()">
<p>Hello, world!</p>
</body>
</html>
動きましたか?
このように onload という属性にコードを書いておくと load イベントという仕組みを使って、 DOM 構築後にそのコードを実行させられることが分かりました。
このように、何かが起こったということをイベントといい、 何かが起こったときに実行されるコードのことをイベントハンドラといいます。
(また、イベントハンドラの書き方は色々あります。 今回は Internet Explorer に対応している標準的な方法として onload 属性を使います。 現在主流な方法は addEventListner や attachEvent を使う方法ですが、 この方法は少し複雑なのでここでは触れません。)
id 属性の値から要素を取得して、要素の内容を書き換えてみよう!
要素の取得には document.getElementById を使い、要素の内容の書き換えには要素の innerHTML プロパティ
以下の例を見てみましょう。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Sample</title>
<script type="text/javascript">
function main() {
// 要素を取得
var element = document.getElementById('target');
// 要素の内容を書き換え
element.innerHTML = 'Hello, <strong>JavaScript</strong>!!';
}
</script>
</head>
<body onload="main()">
<p id="target">Hello, world!</p>
</body>
</html>
要素の名前から要素を取得して、要素の背景色を変えてみよう!
要素の取得には document.getElementsByTagName を使います。 また、要素の背景色を変えるには style プロパティに格納されているオブジェクトの background プロパティを書き換えます。
以下の例を見てみましょう。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Sample</title>
<script type="text/javascript">
function main() {
// p 要素を全部取得
var elements = document.getElementsByTagName('p');
// 要素の背景色を変える
elements[0].style.background = 'red';
elements[1].style.background = 'blue';
}
</script>
</head>
<body onload="main()">
<p>Hello, world!</p>
<p>Hello, world!</p>
</body>
</html>
これも簡単ですね!
cavnas 要素でお絵描き
HTML5 という仕様の canvas 要素という要素を使うと JavaScript から canvas 要素の領域に絵を書くことができるようになります。
この canvas 要素は、現在 Internet Explorer 以外の主要なブラウザで使うことができます。 そして、 Internet Explorer でも excanvas.js という JavaScript を読み込むとこの canvas 要素が使えるようになります。 つまり、ほぼ全てのブラウザで動くってことです!
四角を書いてみよう!
canvas 要素に絵を書くには、まず canvas 要素を取得して getContext 関数で canvas 要素のコンテキストを取得します。
コンテキストを取得してしまえば、コンテキストが持つ様々な関数で描画をすることができます。
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>Sample</title>
<script type="text/javascript">
function main() {
// canvas 要素を取得
var elmCanvas = document.getElementById('canvas');
// コンテキストを取得
var ctx = elmCanvas.getContext('2d');
// 色を指定(青)
ctx.fillStyle = '#00c';
// 左 50px 上 50px の位置に
// 横 100px 縦 100px の四角形を書く
ctx.fillRect(50, 50, 100, 100);
// 色を指定(赤)
ctx.strokeStyle = '#c00';
// 左 100px 上 100px の位置に
// 横 100px 縦 100px の四角形を書く
ctx.strokeRect(100, 100, 100, 100);
}
</script>
</head>
<body onload="main()"><canvas id="canvas" width="400" height="300"></canvas></body>
</html>
丸を書いてみよう!
canvas 要素に絵を書くには、まず canvas 要素を取得して getContext 関数で canvas 要素のコンテキストを取得します。
コンテキストを取得してしまえば、コンテキストが持つ様々な関数で描画をすることができます。
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>Sample</title>
<script type="text/javascript">
function main() {
var ctx = document.getElementById('canvas').getContext('2d');
// 範囲選択開始
ctx.beginPath();
// 左 100 上 px 100px を中心に
// 半径 50 px の円を選択
ctx.arc(100, 100, 50, 0, Math.PI * 2, false);
// 塗る(青)
ctx.fillStyle = '#00c';
ctx.fill();
// 範囲選択終了
ctx.closePath();
}
</script>
</head>
<body onload="main()"><canvas id="canvas" width="400" height="300"></canvas></body>
</html>
cavnas 要素でアニメーション
canvas 要素に書いた絵を動かしてみましょう! え?難しいんじゃないかって?とっても簡単ですよ!
タイマーを使ってみよう!
アニメーションというのは、少し待って、少し動かして、少し待って、少し動かして、の繰り返しです。
それを JavaScript で行うためには、 setInterval という関数を使います。
それでは、実際に setInterval を使ってみましょう。
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>Sample</title>
<script type="text/javascript">
function main() {
var elm = document.getElementById('target');
// 1000 ミリ秒(秒)ごとに
// 第一引数に渡された関数を呼び出す
setInterval(function() { elm.innerHTML = new Date; }, 1000);
}
</script>
</head>
<body onload="main()"><p id="target"></p></body>
</html>
たったこれだけで、時計が出来てしまいました!
canvas 要素の絵を動かしてみよう!
基本はさっきの例と同じです。
絵を消して書き直すというのを繰り返すだけです。
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>Sample</title>
<script type="text/javascript">
function main() {
var ctx = document.getElementById('canvas').getContext('2d');
var x = -100;
var vx = 20;
ctx.fillStyle = '#00c';
setInterval(function() {
ctx.clearRect(0, 0, 400, 300); // 消す
ctx.fillRect(x, 100, 100, 100); // 書く
x += vx; // 位置を更新
}, 40) // を 40 ミリ秒ごとに行う
}
</script>
</head>
<body onload="main()"><canvas id="canvas" width="400" height="300"></canvas></body>
</html>