Entering Passive Mode

カテゴリ 'JavaScript' の記事
< 1 2 3 4 5 >

関数オブジェクトの呼び出し

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 は型を制限できない代わりに、自動的・暗黙の型変換を行う仕組みを持っている。

Undefined と Null

残りの 2 つのプリミティブ値は、undefinednull だ。
これらはよく混同されるので注意が必要である。

undefined は変数(プロパティ)の既定値であり、
存在しないプロパティを参照した際に返される値でもある。

null は、用途は Java や C# と同じで、
空のオブジェクト参照を表すために使われる。

まあ、これくらいは基本だろうから、
これらの値をさらに詳しく考えてみよう。

JavaScript では、変数や戻り値は型を持たず、
常に値そのものが型(実行時型)を持っている。
undefinednull も例外ではなく、それぞれ型が存在する。

それは、Null 型と Undefined 型だ。
これが、残りの 2 つのプリミティブ型である。

基本データを表すプリミティブ型

JavaScript のプリミティブ型には、5 つの型が存在する。
そのうち、基本データを表す 3 つを挙げてみよう。

これらがどのようなデータなのかは説明不要だろう。

プリミティブということに、違和感を感じる人は多いと思う。
というのも、Boolean, Number, String の 3 つの型は、
オブジェクトとして、良く知られているからだ。

JavaScript のデータ型

JavaScript のあらゆる値には、その種類を表す型がある。
型は、大きく 2 つの総称型に分けることができる。
それは、オブジェクト型とプリミティブ型である。
JavaScript にもプリミティブ型が存在するのだ。

オブジェクト型は、値の集合を表す。
オブジェクト型の値(以下、オブジェクト)は連想配列(Hash)であり、
任意の文字列のキーに任意の値を関連付けることができる。
オブジェクトに関連付けれらたキーを、プロパティと呼ぶ。

プロパティが自由に変更できるため、オブジェクトは可変である。
オブジェクトは参照型であるため、
代入を行っても、オブジェクトが複製されることはなく、
同一のオブジェクトが参照される。

それに対して、プリミティブ型は、基本となるデータそのものを表す。
プリミティブ型の値(以下、プリミティブ値)は、
オブジェクトと異なり、プロパティを持つことはできず、
具体的な型に応じた、単一の値のみを保持している。

プリミティブ値は、データの最小単位であるため、その値は不変である。

通常の用途では、これらのデータ型を意識することはほとんどないが、
言語的には、これらは明確に区別されている。

< 1 2 3 4 5 >
このページのトップへ戻る
© 2008 Project Loafer/Project Fireball and all blog writers. Powered by Nucleus CMS