Core JavaScript 1.5 Guide:Working with Objects
出典: MDC
[編集] オブジェクトとプロパティ
JavaScript のオブジェクトには、それに結びつけられたプロパティがあります。簡単な記法でオブジェクトのプロパティにアクセスできます。
objectName.propertyName
オブジェクト名もプロパティ名も大文字と小文字を区別します。プロパティの定義は、そのプロパティに値を代入することで行います。例えば、myCar という名前のオブジェクトがあるとします(今回はオブジェクトが既に存在していると仮定)。次のようにして、そのオブジェクトに make、model、year という名前のプロパティをそれぞれ作成することができます。
myCar.make = "Ford"; myCar.model = "Mustang"; myCar.year = 1969;
配列はある単一の変数名に結びつけられた値の順序集合です。JavaScript におけるプロパティと配列は密接に関連しています。事実、それらは同一のデータ構造への異なるインタフェースなのです。そのため、例えば次のようにして myCar オブジェクトのプロパティにアクセスすることができます。
myCar["make"] = "Ford"; myCar["model"] = "Mustang"; myCar["year"] = 1969;
この手の配列は連想配列として知られています。それぞれのインデックスの要素が文字列にも結びつけられているからです。これがどう動作するかというと、次の関数は引数としてオブジェクトとそのオブジェクトの名前を渡すとオブジェクトのプロパティを表示します。
function show_props(obj, obj_name) {
var result = "";
for (var i in obj)
result += obj_name + "." + i + " = " + obj[i] + "\n";
return result;
}
関数 show_props(myCar, "myCar") を呼び出すと以下の結果が返されます。
myCar.make = Ford myCar.model = Mustang myCar.year = 1969
[編集] 新しいオブジェクトの作成
JavaScript には多くの定義済みオブジェクトがあります。さらに、自分でオブジェクトを作り出すことができます。JavaScript 1.2 以降では、オブジェクト初期化子を用いてオブジェクトを作成できます。もう 1 つの方法として、まずコンストラクタ関数を作成し、それからその関数と new 演算子を用いてオブジェクトのインスタンスを作成することもできます。
- オブジェクト初期化子の使用
- コンストラクタ関数の使用
- オブジェクトのプロパティのインデックス付け
- あるオブジェクトの種類に対するプロパティの定義
- メソッドの定義
- this を用いたオブジェクト参照
- ゲッタとセッタの定義
- プロパティの削除
[編集] オブジェクト初期化子の使用
コンストラクタ関数を使用してオブジェクトを作成する方法だけではなく、オブジェクト初期化子を使用してもオブジェクトを作成することができます。オブジェクト初期化子を使うことはリテラル表示を用いてオブジェクトを作成するということです。「オブジェクト初期化子」は C++ でも同じ意味で使用されている用語です。
オブジェクト初期化子を使用したオブジェクトの構文は次のとおりです。
var obj = { property_1: value_1, // property_# は識別子でもよい
2: value_2, // あるいは数値でもよい
...,
"property_n": value_n }; // あるいは文字列でもよい
ここで、obj は新しいオブジェクトの名前を、各 property_i は識別子(名前、数値、文字列リテラルのいずれか)を、各 value_i はその値を property_i に代入する式をそれぞれ表しています。obj および代入部分はなくてもかまいません。このオブジェクトを別の場所で参照する必要がないのであれば変数に代入する必要はありません。(文が期待されているところにオブジェクトリテラルを置く場合、リテラルを丸括弧で囲み、ブロック文と間違われないようにする必要があるかもしれません。)
トップレベルのスクリプトでオブジェクト初期化子を使用してオブジェクトを作成した場合、JavaScript はオブジェクトリテラルを含む式を評価するたびにそのオブジェクトを解釈します。さらに、関数内で使用された初期化子はその関数が呼び出されるたびに作成されます。
次の文は、式 cond が true の場合かつその場合に限り、あるオブジェクトを作成し、それを変数 x に代入します。
if (cond) x = {hi:"there"};
次の例は 3 つのプロパティを持つ myHonda を作成します。engine プロパティは自らもプロパティを持つオブジェクトでもあることに注意してください。
myHonda = {color:"red",wheels:4,engine:{cylinders:4,size:2.2}};
オブジェクト初期化子を使用して配列を作成することもできます。配列リテラル を参照してください。
JavaScript 1.1 以前ではオブジェクト初期化子を使用することはできません。コンストラクタ関数を使用するか、他のオブジェクトが備えているそのような用途の関数を使用しないとオブジェクトを作成できません。コンストラクタ関数の使用 をご覧ください。
[編集] コンストラクタ関数の使用
もう 1 つの方法として、次の 2 つのステップでオブジェクトを作成することができます。
- コンストラクタ関数を書くことでオブジェクトの種類を定義する。
- new を用いてそのオブジェクトのインスタンスを作成する。
オブジェクトの種類を定義するために、その名前、プロパティ、メソッドを定義する関数を作成する必要があります。例えば、車についてのオブジェクトの種類を作成したいとします。そしてこの種類のオブジェクトに car という名前を付け、make、model、および year というプロパティを持たせたいとします。こうするためには次のような関数を書きます。
function car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
関数に渡された値に基づいてオブジェクトのプロパティに値を代入するために this を使用しています。
すると、次のようにして mycar というオブジェクトを作成することができるようになります。
mycar = new car("Eagle", "Talon TSi", 1993);
この文は mycar を作成し、そのプロパティ用に指定した値を代入します。その結果、mycar.make の値は "Eagle" という文字列、mycar.year は 1993 という整数というようになります。
new を呼び出すことで car オブジェクトをいくらでも作ることができます。
kenscar = new car("Nissan", "300ZX", 1992);
vpgscar = new car("Mazda", "Miata", 1990);
それ自身別のオブジェクトであるというようなプロパティを持つオブジェクトを作ることができます。例えば、次のように person というオブジェクトを定義するとします。
function person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
そして、次のように 2 つの新しい person オブジェクトのインスタンスを作成します。
rand = new person("Rand McKinnon", 33, "M");
ken = new person("Ken Jones", 39, "M");
次のようにして、car の定義を書き換えて、person オブジェクトをとる owner プロパティを持たせることができます。
function car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
}
新しいオブジェクトのインスタンスを作成するために、次のようにします。
car1 = new car("Eagle", "Talon TSi", 1993, rand);
car2 = new car("Nissan", "300ZX", 1992, ken);
新しいオブジェクトの作成時に文字列リテラルや整数値を渡す代わりに、上記の文ではオブジェクト rand および ken を所有者を表す引数として渡しています。car2 の所有者の名前を知りたい場合は次のプロパティにアクセスすることで可能になります。
car2.owner.name
以前に定義したオブジェクトにいつでもプロパティを追加できることに注意してください。例えば次の文
car1.color = "black"
はプロパティ color を car1 に追加し、それに "black" という値を代入します。しかしながら、この方法では他のどのオブジェクトにも影響を与えません。同じ種類の全オブジェクトに新しいプロパティを追加するには、そのプロパティを car というオブジェクトの種類の定義に追加する必要があります。
[編集] オブジェクトのプロパティのインデックス付け
JavaScript 1.0 では、オブジェクトのプロパティを、そのプロパティ名や順序のインデックスで参照できます。しかしながら、JavaScript 1.1 以降では、最初にプロパティをその名前で定義すると、常にその名前で参照しなければならず、また、最初にプロパティをインデックスで定義すると、常にそのインデックスで参照しなければなりません。
先の Car というオブジェクトの種類の例のようにコンストラクタ関数を用いてオブジェクトとそのプロパティを作成したとき、また、それぞれのプロパティを明示的に定義したとき(例:myCar.color = "red")に、これは適用されます。そのため、myCar[5] = "25 mpg" のように、最初にインデックスを用いてオブジェクトのプロパティを定義した場合、myCar[5] のようにそのプロパティを後から参照できるようになります。
このルールの例外は、forms 配列のように HTML から反映されたオブジェクトです。これらの配列内のオブジェクトは、その順番を表す数(文書内のどこにあるかに基づく)か、またはその名前(定義されている場合)のどちらかで常に参照できます。例えば、文書内の 2 番目の <FORM> タグが "myForm" という NAME 属性を持っている場合、document.forms[1] や document.forms["myForm"] や document.myForm とすることでそのフォームを参照できます。
[編集] あるオブジェクトの種類に対するプロパティの定義
prototype プロパティを用いて、定義済みのオブジェクトの種類にプロパティを追加することができます。この方法では、指定した種類のすべてのオブジェクトで共有されるプロパティを定義することになります。そのオブジェクトのあるインスタンス 1 つだけということではありません。次のコードは color プロパティを car という種類の全オブジェクトに追加し、値をオブジェクト car1 の color プロパティに代入します。
car.prototype.color=null; car1.color="black";
詳しくは コア JavaScript リファレンス 内の Function オブジェクトの prototype プロパティ を参照してください。
[編集] メソッドの定義
メソッドとはあるオブジェクトに結びつけられた関数のことです。メソッドは、通常の関数の定義と同じ方法で定義します。既存のオブジェクトに関数を結びつけるには次の構文を使用します。
object.methodname = function_name
ここで、object は既存のオブジェクトを、methodname はメソッドに割り当てる名前を、function_name は関数の名前をそれぞれ表しています。
すると、次のようにしてオブジェクトのコンテキストでそのメソッドを呼び出すことができます。
object.methodname(params);
オブジェクトのコンストラクタ関数にメソッドの定義を含めることで、あるオブジェクトの種類についてのメソッドを定義することができます。例えば、以前に定義した car オブジェクトのプロパティを整形して表示する関数を定義します。
function displayCar() {
var result = "A Beautiful " + this.year + " " + this.make
+ " " + this.model;
pretty_print(result);
}
pretty_print は水平方向の罫線と文字列を表示する関数です。this を使用してそのメソッドを抱えているオブジェクトを参照しています。
次の文
this.displayCar = displayCar;
をオブジェクトの定義に加えることで、この関数を car のメソッドにすることができます。そうすると、car の完全な定義は次のようになります。
function car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
this.displayCar = displayCar;
}
すると、次のようにして各オブジェクトについて displayCar メソッドを呼び出すことができます。
car1.displayCar() car2.displayCar()
こうすると次の図のような出力が得られます。
[編集] this を用いたオブジェクト参照
JavaScript にはカレントオブジェクトを参照するメソッド内で使用できる特殊なキーワード、this があります。例えば、あるオブジェクトの value プロパティの妥当性を確認する validate という関数があるとします。関数にはそのオブジェクトと、上限および下限の値を渡します。
function validate(obj, lowval, hival) {
if ((obj.value < lowval) || (obj.value > hival))
alert("Invalid Value!");
}
各フォーム要素の onchange イベントハンドラにおいて validate を呼び出します。this を使うことで form 要素を渡すことができます。次の例をご覧ください。
<input type="text" name="age" size="3" onChange="validate(this, 18, 99)">
一般に this はあるメソッド内でそのメソッドを呼び出したオブジェクトを参照します。
form プロパティと組み合わせることで、this はカレントオブジェクトの親のフォームを参照できます。次の例では、myForm というフォームに Text オブジェクトとボタンが格納されています。ユーザがボタンをクリックすると、Text オブジェクトの値にフォーム名がセットされます。ボタンの onclick イベントハンドラは this.form を利用して親のフォームである myForm を参照します。
<form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
onclick="this.form.text1.value=this.form.name">
</p>
</form>
[編集] ゲッタとセッタの定義
ゲッタはある特定のプロパティの値を取得するメソッドのことです。セッタはある特定のプロパティの値をセットするメソッドです。どの定義済みコアオブジェクトでも、また、新しいプロパティの追加をサポートしているユーザ定義オブジェクトでゲッタとセッタを定義することができます。ゲッタとセッタの定義にはオブジェクトリテラル構文を使用します。
以下の JS シェルセッションでは、ユーザ定義オブジェクト o についてゲッタとセッタがどう機能するかを説明します。JS シェル とは JavaScript コードをバッチモードで、またはインタラクティブにテストすることができる、開発者向けのアプリケーションのことです。
o オブジェクトのプロパティは以下のとおりです。
- o.a - 数値
- o.b - o.a に 1 を加えて返すゲッタ
- o.c - o.a の値にその値の 1/2 の値をセットするセッタ
js> o = new Object;
[object Object]
js> o = {a:7, get b() {return this.a+1; }, set c(x) {this.a = x/2}};
[object Object]
js> o.a
7
js> o.b
8
js> o.c = 50
js> o.a
25
js>
この JavaScript シェルセッションは、ゲッタとセッタは Date プロトタイプを拡張して定義済み Date クラスの全インスタンスに year プロパティを追加する様子を表しています。Date クラスの既存の getFullYear および setFullYear メソッドを使用して year プロパティのゲッタとセッタをサポートします。
これらの文は year プロパティに対するゲッタとセッタを定義します。
js> var d = Date.prototype;
js> d.__defineGetter__("year", function() { return this.getFullYear(); });
js> d.__defineSetter__("year", function(y) { this.setFullYear(y); });
これらの文は Date オブジェクトでゲッタとセッタを使用しています。
js> var now = new Date; js> print(now.year); 2000 js> now.year=2001; 987617605170 js> print(now); Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
getter = や setter = といった式を使用して新しいゲッタやセッタを既存のオブジェクトで定義するようになっていた時期がありました。この構文は現在は廃止予定であり、現行の JS 1.5 エンジンでは警告を発します。また、将来的には構文エラーになります。使用を避けるようにしてください
[編集] 概要
原則的にゲッタとセッタは次のどちらかに属します。
- オブジェクト初期化子 を用いて定義されたもの
- ゲッタやセッタを追加するメソッドを用いてオブジェクトに後から追加されたもの
オブジェクト初期化子 を用いてゲッタやセッタを定義する際に必ずする必要があることは、ゲッタメソッドの先頭に get を、セッタメソッドの先頭に set をそれぞれ付けることです。セッタメソッドはパラメータ(セットする新しい値)を 1 つだけ受け取るようにしますが、もちろん、ゲッタメソッドはパラメータを受け取るようにしてはいけません。
o = {
a:7,
get b() { return this.a+1; },
set c(x) { this.a = x/2; }
};
ゲッタもセッタも、__defineGetter__ および __defineSetter__ という 2 つの特別なメソッドを用いて、オブジェクト作成後にいつでもそのオブジェクトに追加することができます。両メソッドの第 1 パラメータにはそのゲッタやセッタの名前を文字列という形式で指定します。第 2 パラメータにはゲッタやセッタとして呼び出す関数を指定します。例として前の例の別バージョンを以下に示します。
o.__defineGetter__("b", function() { return this.a+1; });
o.__defineSetter__("c", function(x) { this.a = x/2; });
2 つの形式のうちどちらを選択するかはあなたのプログラミングスタイルおよび目の前の課題次第です。プロトタイプの定義時に既にオブジェクト初期化子を使用しているのであれば、最初の形式を選択するのがよいでしょう。この形式はよりコンパクトかつ自然です。しかしながら、ゲッタやセッタを後から追加する必要がある場合、プロトタイプや特定のオブジェクトを書いていないため、第 2 の形式しか使用できません。第 2 の形式は JavaScript の動的性質をおそらく最もよく表しています。しかし、コードが読みにくく、また理解しにくくなることがあります。
Firefox 3.0 より前のバージョンではゲッタとセッタが DOM 要素に対してサポートされていません。古いバージョンの Firefox では例外を投げることなく失敗します。そのときに例外が必要であれば、HTMLElement のプロトタイプを変更し (HTMLEmenent.prototype.__define[SG]etter__)、例外を投げるようにして回避してください。
Firefox 3.0 では、定義済みのプロパティでゲッタとセッタを定義すると例外が投げられます。そのプロパティは事前に削除しておく必要があります。これは古いバージョンの Firefox には当てはまりません。
[編集] プロパティの削除
delete 演算子を用いることでプロパティを除去することができます。次のコードでプロパティの除去方法を示します。
// 新しいオブジェクト myobj を作成。2 つのプロパティ、a および b を持つ。 myobj = new Object; myobj.a = 5; myobj.b = 12; // a プロパティを除去。myobj には b プロパティだけが残っている。 delete myobj.a;
delete を使用することでグローバル変数を削除することもできます。ただし、これは var キーワードを使用せずにその変数を宣言した場合のみです。
g = 17; delete g;
さらなる情報については delete をご覧ください。
[編集] 定義済みコアオブジェクト
このセクションではコア JavaScript の定義済みオブジェクトについて説明します。
- Array オブジェクト
- Boolean オブジェクト
- Date オブジェクト
- Function オブジェクト
- Math オブジェクト
- Number オブジェクト
- RegExp オブジェクト
- String オブジェクト
[編集] Array オブジェクト
JavaScript には配列を表す明確なデータ型というものはありません。しかし、定義済みの Array オブジェクトとそのメソッドを使用することで、アプリケーションで配列を扱うことができます。Array オブジェクトにはさまざまな方法で配列を操作するメソッドがあります。例えば、配列の要素をつなぎ合わせたり、逆転したり、ソートしたりするものがあります。また、配列の長さを決定するプロパティや、正規表現とともに使用するプロパティもあります。
配列とは、その個々の値を名前やインデックスで参照する順序集合です。例えば、その従業員番号でインデックス付けした、従業員の名前からなる emp という配列を作ることができます。すると、emp[1] は従業員番号 1 を、emp[2] は従業員番号 2 を、というように指すようになります。
[編集] 配列の作成
Array オブジェクトは次のようにして作成します。
1. arrayObjectName = new Array(element0, element1, ..., elementN) 2. arrayObjectName = new Array(arrayLength)
arrayObjectName は新しいオブジェクト名または既存のオブジェクトのプロパティ名です。Array のプロパティやメソッドを用いるときは arrayObjectName は既存の Array オブジェクトの名前または既存のオブジェクトのプロパティ名です。
element0, element1, ..., elementN は配列の要素の値からなるリストです。この形式で指定する際に、配列はその要素として指定した値で初期化されます。また、配列の length プロパティに引数の個数がセットされます。
arrayLength は配列の初期状態の長さです。次のコードは 5 つの要素を持つ配列を作成します。
billingMethod = new Array(5)
配列リテラルも Array オブジェクトです。例えば次のリテラルは Array オブジェクトです。配列リテラルの詳細については 配列リテラル をご覧ください。
coffees = ["French Roast", "Columbian", "Kona"]
[編集] 配列要素の格納
値を要素に代入することで配列要素を格納することができます。
emp[1] = "Casey Jones" emp[2] = "Phil Lesh" emp[3] = "August West"
配列作成時に要素を格納することもできます。
myArray = new Array("Hello", myVar, 3.14159)
[編集] 配列要素の参照
要素の順番を表す数を用いて配列の要素を参照することができます。例えば、次の配列を定義したとします。
myArray = new Array("Wind","Rain","Fire")
すると、その配列の最初の要素は myArray[0] として、第 2 の要素は myArray[1] として参照できるようになります。
要素のインデックスはゼロ (0) から始まりますが、配列の長さ(例:myArray.length)はその配列の要素数を直接表します。
[編集] Array のメソッド
Array オブジェクトには以下のメソッドがあります。
-
concatは 2 つの配列を結合し、新しい配列を返す。
myArray = new Array("1","2","3")
myArray = myArray.concat("a", "b", "c"); // myArray は ["1", "2", "3", "a", "b", "c"] となる
-
join(deliminator = ",")は配列の全要素を結合し、文字列にする。
myArray = new Array("Wind","Rain","Fire")
list = myArray.join(" - "); // list は "Wind - Rain - Fire" となる
-
popは配列から最後の要素を取り除き、その要素を返す。
myArray = new Array("1", "2", "3");
last=myArray.pop(); // MyArray は ["1", "2"] となり、last = "3" となる
-
pushは 1 つ以上の要素を配列の最後に追加し、追加された最後の要素を返す。
myArray = new Array("1", "2");
myArray.push("3"); // MyArray は ["1", "2", "3"] となる
-
reverseは配列の要素を逆順に並び替える。最初の配列要素は最後に、最後のものは最初に来る。
myArray = new Array ("1", "2", "3");
myArray.reverse(); // 配列を並び替え、myArray = [ "3", "2", "1" ] となる
-
shiftは配列から最初の要素を取り除き、その要素を返す。
myArray = new Array ("1", "2", "3");
first=myArray.shift(); // MyArray は ["2", "3"] となり、first は "1" となる
-
slice (start_index, upto_index)は配列の一部分を抽出し、新しい配列を返す。
myArray = new Array ("a", "b", "c", "d", "e");
myArray = myArray.slice(1,4); //インデックス 1 からスタートし、インデックス 4 までの全要素を抽出し、[ "b", "c", "d" ] を返す。
-
splice(index, count_to_remove, addelement1, addelement2, ...)は配列に要素を追加し、かつ/または配列から要素を取り除く。
myArray = new Array ("1", "2", "3", "4", "5");
myArray.splice(1,3,"a","b","c", "d"); // MyArray は ["1", "a", "b", "c", "d", "5"] となる
// このコードはインデックス 1("2" があるところ)からスタートし、そこの 3 要素を取り除き、その場所に連続した要素をすべて挿入する
-
sortは配列の要素をソートする。
myArray = new Array("Wind","Rain","Fire")
myArray.sort(); // 配列をソートし、myArrray = [ "Fire", "Rain", "Wind" ] となる
sort は配列の内容をどうソートするかを決定するコールバック関数をとることもできます。関数は 2 つの値を比較し、3 つの値のうちの 1 つの値を返します。
- ソートシステムにとって a が b より小さい場合、-1(または任意の負数)を返す
- ソートシステムにとって a が b より大きい場合、1(または任意の正数)を返す
- a と b が等価と見なされる場合、0 を返す
例えば、次のコードは配列の最後の文字についてサポートします。
var sortFn = function(a,b){
if (a[a.length - 1] < b[b.length - 1]) return -1;
if (a[a.length - 1] > b[b.length - 1]) return 1;
if (a[a.length - 1] == b[b.length - 1]) return 0;
}
myArray.sort(sortFn); // 配列をソートし、myArray = ["Wind","Fire","Rain"] となる
-
unshiftは 1 つ以上の要素を配列の先頭に追加し、その配列の新しい長さを返す。
[編集] 2 次元配列
次のコードは 2 次元配列を作成します。
a = new Array(4)
for (i=0; i < 4; i++) {
a[i] = new Array(4)
for (j=0; j < 4; j++) {
a[i][j] = "["+i+","+j+"]"
}
}
この例では次の行を持つ配列が作成されます。
0 行目:[0,0][0,1][0,2][0,3] 1 行目:[1,0][1,1][1,2][1,3] 2 行目:[2,0][2,1][2,2][2,3] 3 行目:[3,0][3,1][3,2][3,3]
[編集] 配列と正規表現
配列が正規表現と文字列との間のマッチ結果であるとき、その配列はそのマッチについての情報を持つプロパティと要素を返します。配列は RegExp.exec、String.match、String.split の戻り値です。正規表現とともに配列を使用することに関する情報は、第 4 章の 正規表現 をご覧ください。
[編集] Boolean オブジェクト
Boolean オブジェクトはプリミティブな真偽値型のラッパです。Boolean オブジェクトを作成するには次のような構文を使用します。
booleanObjectName = new Boolean(value)
プリミティブな真偽値の true と false を Boolean オブジェクトの true や false という値と混同しないでください。undefined や、null、0、NaN、空文字列のどれでもない値を持つどんなオブジェクトも、そして false という値を持つ Boolean オブジェクトも、条件文に通されると true に評価されます。詳しくは if...else 文 を参照してください。
[編集] Date オブジェクト
JavaScript には日付を表すデータ型がありません。しかしながら、Date オブジェクトとそのメソッドを使用することで、アプリケーションで日付と時刻を扱うことができます。Date オブジェクトには日付をセット、取得、操作するためのメソッドがたくさんあります。プロパティは一切ありません。
JavaScript は Java と同じように日付を扱います。2 つの言語には共通する日付に関するメソッドが多くあります。また、両言語ともに日付を 1970 年 1 月 1 日 00:00:00 からのミリ秒数として保持します。
Date オブジェクトの範囲は 1970 年 1 月 1 日 (UTC) を基準に -100,000,000 日から 100,000,000 日です。
Date オブジェクトは次のようにして作成します。
dateObjectName = new Date([parameters])
ここで dateObjectName は作成する Date オブジェクトの名前です。すなわち、新しいオブジェクトの名前か、既存のオブジェクトのプロパティ名です。
上記の構文で、parameters は次のどの形式で指定してもかまいません。
- 引数なし:今日の日付と時刻を作成する。例えば、
today = new Date()。 - 次の形式 "月 日, 年 時:分:秒" で日付を表した文字列。例えば、
Xmas95 = new Date("December 25, 1995 13:30:00")。時、分、または秒を省略するとその値はゼロにセットされる。 - 年、月、日を表す整数値のセット。例えば、
Xmas95 = new Date(1995,11,25)。 - 年、月、日、時、分、秒を表す整数値のセット。例えば、
Xmas95 = new Date(1995,11,25,9,30,0)。
JavaScript 1.2 以前
Date オブジェクトは次のように振る舞います。
- 1970 年より前の日付は許されない。
- JavaScript はプラットフォーム特有の日付の便宜や挙動に依存する。つまり、
Dateオブジェクトの挙動はプラットフォームごとに異なる。
[編集] Date オブジェクトのメソッド
Date オブジェクトの日付や時刻を扱うメソッドは、大まかに次のカテゴリに分けることができます。
- "set" メソッド:日付や時刻の値を
Dateオブジェクトにセットする。 - "get" メソッド:
Dateオブジェクトから日付や時刻の値を取得する。 - "to" メソッド:
Dateオブジェクトから文字列の値を返す。 - parse および UTC メソッド:
Date文字列をパースする。
"get" および "set" メソッドを用いることで、秒、分、時、日にち、曜日、月、年を別々に取得したりセットしたりすることができます。曜日を返す getDay メソッドというものがありますが、これに対応する setDay メソッドというものはありません。なぜならば、曜日は自動的にセットされるからです。これらのメソッドはこれらの値を表すのに整数を用います。
- 秒および分:0 から 59
- 時:0 から 23
- 曜日:0(日曜)から 6(土曜)
- 日にち:1 から 31
- 月:0(1 月)から 11(12 月)
- 年:1900 年から数えた年
例えば、次の日付を定義したとします。
Xmas95 = new Date("December 25, 1995")
すると、Xmas95.getMonth() は 11 を返し、Xmas95.getFullYear() は 1995 を返します。
getTime メソッドや setTime メソッドは日付を比較するのに便利です。getTime メソッドは 1970 年 1 月 1 日 00:00:00 からのミリ秒数を返します。
例えば、次のコードはその年の残りの日数を表示します。
today = new Date() endYear = new Date(1995,11,31,23,59,59,999) // 日と月をセット endYear.setFullYear(today.getFullYear()) // 今年が何年かをセット msPerDay = 24 * 60 * 60 * 1000 // 1 日のミリ秒数をセット daysLeft = (endYear.getTime() - today.getTime()) / msPerDay daysLeft = Math.round(daysLeft) // その年の残り日数を返す
この例では今日の日付を保持する today という名前の Date オブジェクトを作成します。そして endYear という名前の Date オブジェクトを作成し、その年が何年かという値をセットします。さらに、1 日のミリ秒数を用いて今日と endYear の間の日数を算出します。これには getTime を使用し、さらに全体の日数に丸めます。
parse メソッドは、日付を表す文字列から既存の Date オブジェクトに値を代入するのに便利です。例えば、次のコードは parse と setTime を用いて日付の値を IPOdate オブジェクトに代入します。
IPOdate = new Date()
IPOdate.setTime(Date.parse("Aug 9, 1995"))
[編集] Date オブジェクトの使用例
次の例では、関数 JSClock() はデジタル時計のような形式で時刻を返します。
function JSClock() {
var time = new Date()
var hour = time.getHours()
var minute = time.getMinutes()
var second = time.getSeconds()
var temp = "" + ((hour > 12) ? hour - 12 : hour)
if (hour == 0)
temp = "12";
temp += ((minute < 10) ? ":0" : ":") + minute
temp += ((second < 10) ? ":0" : ":") + second
temp += (hour >= 12) ? " P.M." : " A.M."
return temp
}
JSClock 関数はまず time という新しい Date オブジェクトを作成します。引数は与えられないため、現在の日付と時刻から time が作成されます。そして getHours、getMinutes および getSeconds メソッドを呼び出し、現在の時間、分、秒の値を hour、minute、second にそれぞれ代入します。
その次の 4 つの文はその時刻を元に文字列の値を構築します。最初の文は変数 temp を作成し、それに条件式を用いて値を代入します。hour が 12 よりも大きい場合は (hour - 12) を、それ以外の場合は単純に hour をそれぞれ代入します。ただし hour が 0 の場合は 12 とします。
その次の文は minute の値を temp に付け加えます。minute の値が 10 より小さい場合、条件式は区切りのコロンと分の先頭のゼロを追加し、そうでない場合は区切りのコロンだけを追加します。そして同様にして秒の値を temp に付け加えます。
最後に、条件式は hour が 12 以上の場合は "PM" を、そうでない場合は "AM" をそれぞれ temp に付け加えます。
[編集] Function オブジェクト
定義済みの Function オブジェクトは、関数としてコンパイルさせたい JavaScript コードの文字列を指定します。
Function オブジェクトを作成するには次のようにします。
functionObjectName = new Function ([arg1, arg2, ... argn], functionBody)
functionObjectName は変数名または既存のオブジェクトのプロパティ名です。オブジェクトに小文字のイベントハンドラ名を続けて、window.onerror のようにして指定することもできます。
arg1, arg2, ... argn は関数が仮引数名として使用する引数です。それぞれが JavaScript の識別子として妥当な文字列である必要があります。例えば、"x" や "theForm" などです。
functionBody は関数の本体としてコンパイルさせたい JavaScript コードを表す文字列です。
Function オブジェクトはそれが使用されるたびに評価されます。これは関数を宣言し、それをコード内で呼び出す方法よりも非効率的です。宣言された関数はコンパイルされるからです。
ここで説明した関数の定義方法に加えて、function 文と関数式を用いることもできます。詳しくは コア JavaScript 1.5 リファレンス を参照してください。
次のコードは関数を変数 setBGColor に代入します。この関数は開いている文書の背景色をセットします。
var setBGColor = new Function("document.bgColor='antiquewhite'")
Function オブジェクトを呼び出すには、それがあたかも関数であるかのように変数名を指定すればいいのです。次のコードは setBGColor 変数で指定された関数を実行します。
var colorChoice="antiquewhite"
if (colorChoice=="antiquewhite") {setBGColor()}
次のどちらかの方法を使用することでイベントハンドラに関数を代入することができます。
1. document.form1.colorButton.onclick=setBGColor
2. <INPUT NAME="colorButton" TYPE="button"
VALUE="Change background color"
onClick="setBGColor()">
上記の変数 setBGColor を作成することは次の関数を宣言することと同じようなことです。
function setBGColor() {
document.bgColor='antiquewhite'
}
関数を変数に代入することは関数を宣言することと似ていますが、異なる点もあります。
-
var setBGColor = new Function("...")のようにして関数を変数に代入すると、setBGColorはnew Function()を用いて作成した関数への参照がその値であるような変数になります。 -
function setBGColor() {...}のようにして関数を作成すると、setBGColorは変数ではなく関数の名前になります。
関数を関数の中に入れ子にすることができます。内側の関数は外側の関数に対してプライベートになります。
- 内側の関数には外側の関数の文からしかアクセスできません。
- 内側の関数は外側の関数の引数や変数を使用できます。外側の関数は内側の関数の引数や変数を使用できません。
[編集] Math オブジェクト
定義済みの Math オブジェクトには数学的な定数や関数を実現するプロパティやメソッドがあります。例えば、Math オブジェクトの PI プロパティは円周率の値 (3.141...) を表します。これはアプリケーションでは次のように使用します。
Math.PI
同様に、標準的な数学関数が Math のメソッドになっています。これは三角関数、対数関数、指数関数などがあります。例えば、三角関数のサインを使用したい場合は次のように書きます。
Math.sin(1.56)
Math の三角関数のメソッドはすべてラジアンの引数をとります。
次の表で Math オブジェクトのメソッドを簡単に説明します。
| メソッド | 説明 |
|---|---|
| abs | 絶対値。 |
| sin, cos, tan | 標準的な三角関数。引数はラジアン。 |
| acos, asin, atan, atan2 | 逆三角関数。ラジアンの値を返す。 |
| exp, log | 指数関数と自然対数。底は e。 |
| ceil | 引数以上の整数のうち、最小のものを返す。 |
| floor | 引数以下の整数のうち、最大のものを返す。 |
| min, max | 2 つの引数のうち、大きいもの、小さいものをそれぞれ返す。 |
| pow | 累乗。第 1 引数は底、第 2 引数は指数。 |
| random | 0 から 1 までの乱数を返す。 |
| round | 引数を直近の整数に丸める。 |
| sqrt | 平方根。 |
表 7.1:Math のメソッド
他の多くのオブジェクトとは異なり、決して自分用の Math オブジェクトを作成してはいけません。常に定義済みの Math オブジェクトを使用してください。
[編集] Number オブジェクト
Number には、最大値、非数、無限大といった数値定数を表すプロパティがあります。これらのプロパティの値を変更することはできません。これらは次のように使用します。
biggestNum = Number.MAX_VALUE smallestNum = Number.MIN_VALUE infiniteNum = Number.POSITIVE_INFINITY negInfiniteNum = Number.NEGATIVE_INFINITY notANum = Number.NaN
常に上記のようにして定義済みの Number オブジェクトのプロパティを参照します。自分で作成した Number オブジェクトのプロパティとして参照するのではありません。
次の表では Number オブジェクトのプロパティについて簡単に説明します。
| プロパティ | 説明 |
|---|---|
| MAX_VALUE | 最大の表現可能な値 |
| MIN_VALUE | 最小の表現可能な値 |
| NaN | 特殊な "not a number"(非数)の値 |
| NEGATIVE_INFINITY | 特殊な負の無限大。オーバフロー時に返される。 |
| POSITIVE_INFINITY | 特殊な正の無限大。オーバフロー時に返される。 |
表 7.2:Number のプロパティ
Number のプロトタイプは Number オブジェクトから情報を様々な形で取り出すメソッドを備えています。次の表では Number.prototype のメソッドについて簡単に説明します。
| メソッド | 説明 |
|---|---|
| toExponential | 数値を指数表示の文字列にして返す。 |
| toFixed | 数値を固定小数点表示の文字列にして返す。 |
| toPrecision | 数値を指定した精度の固定小数点表示の文字列にして返す。 |
| toSource | 指定した Number オブジェクトをオブジェクトリテラルにして返す。この値を利用して新しいオブジェクトを作成できる。Object.toSource メソッドを上書きする。 |
| toString | 指定したオブジェクトを文字列にして返す。Object.toString メソッドを上書きする。 |
| valueOf | 指定したオブジェクトのプリミティブ値を返す。Object.valueOf メソッドを上書きする。 |
表 7.3:Number.prototype のメソッド
[編集] RegExp オブジェクト
RegExp オブジェクトを用いることで正規表現が使用できるようになります。これは第 4 章の 正規表現 で説明しています。
[編集] String オブジェクト
String オブジェクトにはプロパティが 1 つあります。それは length で、これは文字列中の文字の数を表します。例えば、次のコードは x に 13 という値を代入します。"Hello, World!" は 13 文字だからです。
mystring = "Hello, World!" x = mystring.length
String オブジェクトには 2 種類のメソッドがあります。これは、substring や toUpperCase のような、その文字列そのものを変形させたものを返すものと、bold や link のような、その文字列を HTML として整形したものを返すものです。
例えば先の例を流用すると、mystring.toUpperCase() も "hello, world!".toUpperCase() も、"HELLO, WORLD!" という文字列を返します。
substring メソッドは 2 つの引数をとり、その 2 つの引数の間の文字列のサブセットを返します。先の例を流用すると、mystring.substring(4, 9) は "o, Wo" という文字列を返します。詳しくは コア JavaScript リファレンス の String オブジェクトの substring メソッドを参照してください。
String には自動的に HTML に整形するメソッドも多くあります。これは太字のテキストを生成する bold や、ハイパーリンクを生成する link などがあります。例えば、link メソッドを用いてある架空の URL へのハイパーリンクを作成するには次のようにします。
mystring.link("http://www.helloworld.com")
次の表で String オブジェクトのメソッドについて簡単に説明します。
| メソッド | 説明 |
|---|---|
| anchor | HTML の名前付きアンカを作成する。 |
| big, blink, bold, fixed, italics, small, strike, sub, sup | HTML の整形済み文字列を作成する。 |
| charAt, charCodeAt | 文字列中の指定した位置の文字または文字コードを返す。 |
| indexOf, lastIndexOf | 文字列中の指定した部分文字列の位置や指定した部分文字列の最後の位置をそれぞれ返す。 |
| link | HTML のハイパーリンクを作成する。 |
| concat | 2 つの文字列を連結し、新しい文字列を返す。 |
| fromCharCode | 指定した Unicode 値の連続から文字列を構成する。これは String クラスのメソッドであり、String インスタンスのものではない。 |
| split | String オブジェクトを文字列の配列に分配する。文字列を部分文字列に分割することで行う。 |
| slice | 文字列から一部分を抽出し、新しい文字列を返す。 |
| substring, substr | 文字列の指定したサブセットを返す。開始および終了のインデックス、または開始のインデックスおよび長さのいずれかを指定する。 |
| match, replace, search | 正規表現を取り扱う。 |
| toLowerCase, toUpperCase | 文字列をすべて小文字に、またはすべて大文字にしてそれぞれ返す。 |
表 7.4:String インスタンスのメソッド
[編集] 文字列リテラルは String オブジェクトとは別物
String オブジェクトは文字列のプリミティブデータ型のラッパです。文字列リテラルと String オブジェクトを混同してはいけません。例えば、次のコードでは文字列リテラルの s1 と String オブジェクトの s2 を作成します。
s1 = "foo" // 文字列リテラルの値を作成
s2 = new String("foo") // String オブジェクトを作成
文字列リテラルの値でなら、String オブジェクトのどんなメソッドでも呼び出すことができます。JavaScript が自動的に文字列リテラルを一時的な String オブジェクトに変換し、メソッドを呼び出し、その一時的な String オブジェクトを破棄するのです。String.length プロパティを文字列リテラルで使うこともできます。
特に String オブジェクトを使う必要がない場合は文字列リテラルを使うようにしてください。String オブジェクトは直観的ではない挙動をとることがあるからです。次の例をご覧ください。
s1 = "2 + 2" // 文字列リテラルの値を作成
s2 = new String("2 + 2")// String オブジェクトを作成
eval(s1) // 数値 4 を返す
eval(s2) // 文字列 "2 + 2" を返す
