最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
function foo() {
;
}
var obj = new Object();
obj.foo = foo;
var x = foo();
var y = new foo();
var z = obj.foo();
関数オブジェクトには 3 つの用途があることが分かった。
他の言語では、これらは独立していることが多いが、
JavaScript では、全て関数オブジェクトを利用する。
これらを区別するのは、その呼び出し方法である。
function getThisValue() {
return this.value;
}
function setThisValue(value) {
this.value = value;
}
function Foo() {
this.value = 0;
this.getValue = getThisValue;
this.setValue = setThisValue;
}
var foo = new Foo();
foo.setValue(3 * 5);
alert(foo.getValue()); // 15
JavaScript では、メソッドもまた関数オブジェクトである。
JavaScript においては、メソッドはプロパティの一種であり、
オブジェクトのプロパティに関数オブジェクトを代入すると、
それはメソッドとして呼び出せるようになる。
function Foo(x, y) {
this.value = x * y;
}
var foo = new Foo(3, 5);
alert(foo.value); // 15
alert(typeof foo); // object
new 演算子で関数オブジェクトを呼び出す事で、
他のプログラミング言語同様、
オブジェクトを生成することができる。
foo = new Object(); foo.property = 12345;
bar = new Function("x, y", "return x * y;");
baz = new Array(123, "abc", null);
qux = new String("String object");
quux = new Boolean(true);
corge = new Number(12345);
grault = new Date();
garply = new RegExp("\\d+");
waldo = new Error("No way.");
プリミティブ値はリテラル記法で表現したが、
オブジェクトは主に new 演算子を使って生成する。
Function オブジェクトに関しては、
function キーワードを使って作成するのが普通だが、
他と同様、new 演算子で作成することも可能だ。
JavaScript でのオブジェクト生成構文は、
Java や C++ に近くなるように設計されている。
ただ、JavaScript ではその文の意味合いが大きく異なる。
function invoke(func, x, y) {
return func(x, y);
}
function foo(x, y) {
return x * y;
}
foo.value = invoke(foo, 3, 5);
var bar = foo;
alert(bar.value);
alert(foo.toString());
alert(foo === bar);
JavaScript では、関数はオブジェクトの一種である。
関数は、通常のオブジェクトとしての特性に加え、
() 構文で「呼び出し可能」という特徴を持つ、
特別なオブジェクトとして扱われる。
var value = "String Literal"; var length = value.length; alert(length); var value2 = "String Literal"; value2.property = 12345; alert(value2.property);
Number, String, Boolean の 3 つの型には、
プリミティブとオブジェクトの両方の型が存在する。
違いは、プロパティを持てるか持てないかだ。
暗黙の型変換が、色々な場所で適応されるため、
各型に対応するプリミティブ値とオブジェクトは、
ほぼ区別することなく透過的に扱うことができる。
また、JavaScript のプロパティアクセサ構文は
プリミティブ値に対しても記述することができるため、
構文上、プリミティブ値にプロパティがあるように見える。
これらの言語機能は強力なのだが、プリミティブ値とオブジェクトが、
単一の同じ型であるという誤解を生む原因ともなっている。
if (new Boolean(false) && "false") {
alert("Oops!");
}
変数や関数の引数に型を制限できる、型に厳密なプログラミング言語では、
ソースコードを解析した時点で、互換性がない型の値を検出できる。
しかし、JavaScript の値の型は常に実行時に決まる。
なので、原則として、その文を実行するまで、
どのような型が渡されるかは検出できない。
これが何を意味するかというと、関数の引数等、外部から受け取る値については、
設計者が想定している型である保障がないため、
値を使う前に、型を確認する必要があるということだ。
だが、常に型を確認するということは、コーディングの苦痛以外の何者でもないため、
JavaScript は型を制限できない代わりに、自動的・暗黙の型変換を行う仕組みを持っている。
残りの 2 つのプリミティブ値は、undefined と null だ。
これらはよく混同されるので注意が必要である。
undefined は変数(プロパティ)の既定値であり、
null は、用途は Java や C# と同じで、
まあ、これくらいは基本だろうから、
JavaScript では、変数や戻り値は型を持たず、
それは、Null 型と Undefined 型だ。
JavaScript のプリミティブ型には、5 つの型が存在する。
そのうち、基本データを表す 3 つを挙げてみよう。
これらがどのようなデータなのかは説明不要だろう。
プリミティブということに、違和感を感じる人は多いと思う。
というのも、Boolean, Number, String の 3 つの型は、
オブジェクトとして、良く知られているからだ。
JavaScript のあらゆる値には、その種類を表す型がある。
型は、大きく 2 つの総称型に分けることができる。
それは、オブジェクト型とプリミティブ型である。
JavaScript にもプリミティブ型が存在するのだ。
オブジェクト型は、値の集合を表す。
オブジェクト型の値(以下、オブジェクト)は連想配列(Hash)であり、
任意の文字列のキーに任意の値を関連付けることができる。
オブジェクトに関連付けれらたキーを、プロパティと呼ぶ。
プロパティが自由に変更できるため、オブジェクトは可変である。
オブジェクトは参照型であるため、
代入を行っても、オブジェクトが複製されることはなく、
同一のオブジェクトが参照される。
それに対して、プリミティブ型は、基本となるデータそのものを表す。
プリミティブ型の値(以下、プリミティブ値)は、
オブジェクトと異なり、プロパティを持つことはできず、
具体的な型に応じた、単一の値のみを保持している。
プリミティブ値は、データの最小単位であるため、その値は不変である。
通常の用途では、これらのデータ型を意識することはほとんどないが、
言語的には、これらは明確に区別されている。