前回は、インタプリタ言語、動的型言語など JavaScript の言語仕様についてまとめた。ここでは、5つの基本型とオブジェクト型という合計6つの型がある JavaScript の型について解説する。
1 型とは
型とは対象の特徴を決定づけるものである。JavaScriptには以下の5つの基本型がある。
- 文字列型
- 数値型
- ブーリアン型
- null型
- undefined型
5つの基本型以外をオブジェクト型と呼ぶ。つまりJavaScriptの型は6種類に分類できる。なお、基本型のインスタンスを「値」と呼び、オブジェクト型のインスタンスをオブジェクトと呼ぶ。
型に関してJavaとの比較
型に関してJavaScriptとJavaの比較は以下の2つである。1つは動的型と静的型という視点、もう1つはクラスベースとプロトタイプベースの視点である。前者では、Javaのように変数に型のある言語を静的型言語、JavaScriptのように型のない言語を動的型言語と呼ぶ。後者では、Javaのようにユーザが型を定義するスタイルをクラスベース、JavaScriptのようにプロトタイプオブジェクトで型を定義するスタイルをプロトタイプベースという。
基本型と参照型
JavaScriptの変数は概念上、基本型変数と参照型変数に分類できる。基本型変数は数値などの値そのものを持ち、参照型変数はオブジェクトの参照を持つ。
2 組み込み型の概要
ECMAScriptの仕様書は、組み込み型(built-in type)を5つの基本型とオブジェクト型に分類する。仕様書に基本型(primitive type)の用語はなく、代わりに基本値(primitive value)の用語が使われている。ここでは基本型の用語を用いる。
JavaScriptの基本型
JavaScriptの文字列型は基本型である。Javaは文字列型は基本型ではないが、オブジェクト型なため見かけほど大きな違いにはならない。JavaScriptの数値型は1種類で、内部表現は64ビットの浮動小数点数である。ブーリアン型はJavaとJavaScriptで違いはない。null型は値としてnullのみが存在する方である。undefined型は未定義を意味する値の型である。
3 文字列型
文字列値リテラル
文字列値は文字列リテラルで表記できる。文字列リテラルはダブルクォーテーション(”)もしくはシングルクォーテーション(’)で囲む。特別な文字表記にはエスケープシーケンスを使う。エスケープシーケンスとはエスケープ文字を使って後続する文字に特別な意味を持たせる表記方法のことである。その一覧は以下の通り。
- \n:改行(LF)
- \t:タブ
- \b:ベル
- \r:改行(CR)
- \f:フィード
- \v:垂直タブ
- \\:バックスラッシュ
- \’:シングルクォート
- \”:ダブルクォート
- \xXX:Latin-1 のコードポイント
- \uXXXX:Unicode のコードポイント
文字列型の演算
以前述べたように=演算子の右辺に文字列値を書くと左辺の変数に値を代入できる。また、代入の右辺に文字列値を持つ変数を書くと、右辺の文字列値を左辺の変数に代入できる。JavaScriptの文字列型は不変型なのでそもそも文字列値を変更できない。
文字列型の比較
JavaScriptには2つの同値比較演算子がある。==と===である。それぞれに対応する否定演算子の!==と!=もある。==と===の違いは比較時に型変換をするかしないかである。JavaScriptの文字列値は大小比較演算が可能である。>演算子、>=演算子、<演算子、<=演算子である。比較はUnicodeの文字コード値(コードポイント)ベースである。現実的には、意味のある大小比較が行えるのは英単語のみである。
文字列クラス(Stringクラス)
文字列クラスの名前はStringである。JavaScriptの文字列型とStringクラスの関係は、Javaでの数値型とラッパー型(NumberクラスやIntegerクラス)の関係とほぼ同じである。相互に暗黙の型変換がある。
文字列オブジェクト
文字列オブジェクトを明示的に生成するにはnew演算子を使う。文字列値と文字列オブジェクトは相互に暗黙に型変換される。
文字列値と文字列オブジェクトの混乱の回避
必要であればtypeof演算で文字列値と文字列オブジェクトを判定できる。文字列オブジェクトのtypeof演算結果は”object”である。また、文字列値と文字列オブジェクトの混乱を回避するには、明示的にnew String()をしないことである。
String関数呼び出し
String関数は明示的な型変換のために使う。
Stringクラスの機能
Stringクラスの関数またはコンストラクタ呼び出しは以下の2つ。
- String([value]):引数valueを文字列値に型変換
- new String([value]):Stringインスタンスを生成
Stringクラスのプロパティは以下の3つ。
- fromCharCode([char0[, char1, …]]):引数valueを文字列値に型変換
- length:値は1
- prototype:プロトタイプチェーン用
String.prototypeオブジェクトのプロパティは以下の通り。
- charAt(pos):インデックスposの位置の文字を持つ長さ1の文字列値を返す
- charCodeAt(pos):インデックスposの位置の文字の文字コードを数値で返す
- concat([string0, string1, …]):引数の文字列値を連結して、新しい文字列値を返す
- constructor:Stringクラスオブジェクトへの参照
- indexOf(searchString[, pos]):文字列値searchStringが最初に見つかるインデックス値を返す
- localeCompare(that):ロケール依存の文字列比較
- match(regexp):正規表現regexpのマッチ結果を返す
- quote():JavaScript独自拡張
- replace(searchValue, replaceValue):searchValue(正規表現または文字列値)をreplaceValue(文字列または関数)で置換した文字列を返す
- search(regexp):正規表現regexpのマッチ結果を返す
- slice(start, end):値引数startから引数endまでの部分文字列を新しい文字列値で返す
- split(separator, limit):引数separatorの文字列もしくは正規表現で文字列を分割して、文字列値の配列を返す
- substr(start[, length]):JavaScript独自拡張
- substring(start, end):引数startから引数endまでの部分文字列を新しい文字列値で返す
- toLocaleLowerCase():文字列の各文字をロケール依存の小文字に変換
- toLocaleUpperCase():文字列の各文字をロケール依存の大文字に変換
- toLowerCase():文字列の各文字を小文字に変換
- toSource():JavaScript独自拡張
- toString():Stringインスタンスから文字列値に変換
- toUpperCase():文字列の各文字を大文字に変換
- trim():文字列前後の空白を除去
- trimLeft():JavaScript独自拡張
- trimRight():JavaScript独自拡張
- valueOf():Stringインスタンスから文字列値に変換
Stringクラスのインスタンスプロパティは以下の2つ。
- (内部プロパティ):文字列値
- length:文字列長(文字数)
非破壊的なメソッド
非破壊的メソッドとは状態を変更しないメソッドである。
4 数値型
数値リテラル
JavaScriptの数値の内部は64ビットの浮動小数点数である。整数型と浮動小数点数型の使い分けがないので、型変換にまつわるバグから解放される。JavaScriptには8進数の数値リテラルがある。
数値型の演算
数値に対する4則演算には、+、-、*、/記号の演算子を使う。%記号を使う剰余演算(割り算の余りを求める演算)もある。
浮動小数点数の一般的注意
浮動小数点数はそもそも小数点以下を正確に表現できないことがある。また、浮動小数点数で正確な実数計算は不可能である。実数を正確に扱う必要がある場合、JavaのBigDecimal相当の実数ライブラリを使う必要がある。
数値クラス(Numberクラス)
文字列クラス(Stringクラス)があるように、数値クラス(Numberクラス)が存在する。文字列値と文字列オブジェクトが相互に暗黙の型変換でほぼ等価に扱えるとの同様、数値と数値オブジェクトもほぼ等価に扱える。数値オブジェクトを明示的に生成するにはnew演算子を使う。
Number関数呼び出し
Number関数も普通の関数呼び出しをすると数値を返す。明示的な型変換のために使える。引数を数値に型変換できない場合のNumber関数の結果はNaNになる。
Numberクラスの機能
Numberクラスの関数またはコンストラクタ呼び出しは以下の2つ。
- Number([value]):引数valueを数値に型変換
- new Number([value]):Numberインスタンスを生成
Numberクラスのプロパティは以下の7つ。
- prototype:プロトタイプチェーン用
- length:値は1
- MAX_VALUE:64ビット浮上小数点数の扱える正の最大値
- MIN_VALUE:64ビット浮動小数点数の扱える正の最小値
- NaN:Not a Numberを示す値
- NEGATIVE_INFINITY:負の無限大を示す値
- POSITIVE_INFINITY:正の無限大を示す値
Number.prototypeオブジェクトのプロパティは以下の8つ。
- constructor:Numberクラスオブジェクトへの参照
- toExponential(fractionDigits):指数表示の文字列値に変換
- toFixed(fractionDigits):小数点表示の文字列値に変換
- toLocaleString():ロケール依存の文字列値に変換
- toPrecision(precision):小数点表示の文字列値に変換
- toSource():JavaScript独自拡張
- toString([radix]):Numberインスタンスから文字列値に型変換
- valueOf():Numberインスタンスから数値に型変換
Numberクラスのインスタンスプロパティは以下の1つ。
- (内部プロパティ):数値
境界値と特別な数値
64ビットの浮動小数点数の扱える正の最大値と最小値はNumberオブジェクトのプロパティ値で得られる。先頭にマイナス記号(演算子)をつけて負数の最大値、最小値を得られる。
NaN
NaNは演算してもNaN以外に戻ることはない。また、他のどんな数値とも同値にならないだけではなくNaN同士の同値判定すら偽になることである。
5 ブーリアン型
ブーリアン値
ブーリアン型は論理値型や真偽値型ともいえる。ブーリアン型の取りうる値は真(true)か偽(false)の2値だけである。trueとfalseはリテラル値として定義されている。
ブーリアンクラス(Booleanクラス)
ブーリアン型のラッパー型に相当するブーリアンクラス(Booleanクラス)が存在する。位置づけや使い方はStringクラスやNumberクラスと同じである。同様に、new演算子でブーリアンオブジェクトを明示的に生成できる。
Booleanクラスの機能
Booleanクラスの関数またはコンストラクタ呼び出しは以下の2つ。
- Boolean(value):引数valueをブーリアン値に型変換
- new Boolean(value):Booleanインスタンスを生成
Booleanクラスのプロパティは以下の2つ。
- prototype:プロトタイプチェーン用
- length:値は1
Boolean.prototypeオブジェクトのプロパティは以下の4つ。
- constructor:Booleanクラスオブジェクトへの参照
- toSource():JavaScript独自拡張
- toString():Booleanインスタンスから文字列値に変換
- valueOf():Booleanインスタンスからブーリアン値に型変換
Booleanクラスのインスタンスプロパティは以下の2つ。
- (内部プロパティ):ブーリアン値
- toSource():JavaScript独自拡張
6 null型
null型はオブジェクト参照との関係で意味を持つ。null値の本来的な意味は「何も参照していない」状態である。null型の取りうる値はnull値の1値だけである。null値はリテラル値である。
7 undefined型
undefined型の取りうる値はundefined値の1値だけである。定義済みグローバル変数である。
undefined値
undefined値は明示的に値を代入していない変数の初期値である。未定義値や未初期化値とも呼ぶ。つまり、言語仕様でundefinedという識別子は必須ではない。
8 オブジェクト型
基本型以外の型はすべてオブジェクト型である。
関数型
JavaScriptに関数型という方があるかどうかは議論が分かれる。著者の見解では、関数はオブジェクト型と認識すれば十分としている。
9 型変換
JavaScriptは型変換に起因するバグが発生しやすい言語である。弱い型付けのため暗黙の型変換が多いからである。式の中に書いた値も演算子に応じて型変換される。
文字列値から数値の型変換
文字列値から数値への明示的な型変換は、Number関数、parseInt関数、parseFloat関数を使うのが定石である。また、数値演算のオペランドに文字列値を書くと暗黙に数値に型変換される。
数値から文字列値の型変換
数値から文字列値の明示的な型変換は、String関数もしくは数値オブジェクトに暗黙に型変換してからtoStringメソッドを呼ぶのが定石である。また、文字列演算のオペランドに数値を書くと暗黙に文字列値に型変換される。
型変換のイディオム
最短表記の型変換は以下の通り。
// 数値から文字列値
js> var n = 3;
js> n+”;
// 文字列値から数値
js> var s = ‘3’;
js> +s;
ブーリアン型への型変換
実用上、ブーリアン型への型変換は重要である。if文やwhile文などの条件式で暗黙の型変換が多いからである。
その他の型変換
ブーリアン値とnull値とundefined値からの型変換もある。例えば、true-1-‘true’。
オブジェクト型から基本型への型変換
オブジェクト型からの型変換は以下の通り。
- 文字列型:String(obj)。toStringメソッドの結果を文字列型に変換
- 数値型:Number(obj)。valueOfメソッドの結果
- ブーリアン型:Boolean(obj)。常にtrue
- undefined値:NaN。’undefined’
基本型からオブジェクト型への型変換
基本型からオブジェクト型への型変換の規則は以下の通り。
- 文字列型:Stringオブジェクト
- 数値型:Numberオブジェクト
- ブーリアン型:Booleanオブジェクト
- null型:Errorオブジェクト
- undefined型:Errorオブジェクト
最後に
5つの基本型とは、文字列型、数値型、ブーリアン型、null型、undefined型である。文字列型は基本型である。数値型は1種類で、内部表現は64ビットの浮動小数点数である。ブーリアン型はJavaとJavaScriptで違いがない。null型は値としてnullのみが存在する型である。undefined型は未定義を意味する値の型である。5つの基本型以外の型はすべてオブジェクト型である(詳細は後述)。
次回は、JavaScriptの文法規則 文、式、演算子についてまとめる。
![]() |