GitBookjs-primerデータ型とリテラルデータ型JavaScriptは動的型付け言語に分類される言語であるため、静的型付け言語のような変数の型はありません。いった値の型は存在します。これらの値の型のことをデータ型と呼びます。データ型を大きく分けると、プリミティブ型とオブジェクトの2つに分類されます。プリミティブ型(基本型)は、真偽値や数値などの基本的な値の型のことです。プリミティブ型の値は、一度作成したらその値自体を変更できないというイミュータブル(immutable)の特性を持ちます。JavaScriptでは、文字列も一度作成したら変更できないイミュータブルの特性を持ち、プリミティブ型の一種として扱われます。オブジェクトは複数のプリミティブ型の値またはオブジェクトからなる集合です。オブジェクトは、一度作成した後もその値自体を変更できるためミュータブル(mutable)の特性を持ちます。オブジェクトは、値そのものではなく値への参照を経由して操作されるため、参照型のデータとも言います。データ型を細かく見ていくと、6つのプリミティブ型とオブジェクトからなります。Dateなどプリミティブ型でないものは、オブジェクトであると覚えていれば問題ありません。typeof演算子を使うことで、次のようにデータ型を調べることができます。nullが"object"となるのは、歴史的経緯のある仕様のバグ1です。他のプリミティブ型の値については、typeof演算子でそれぞれのデータ型を調べることができます。一方で、配列とオブジェクトがどちらも"object"という判定結果になります。このように、typeof演算子ではすべてのオブジェクトの種類を判定することはできません。基本的にtypeof演算子は、プリミティブ型またはオブジェクトかを判別するものです。オブジェクトの詳細な種類を判定できないことは、覚えておくとよいでしょう。各オブジェクトの判定方法については、それぞれのオブジェクトの章で見ていきます。リテラルプリミティブ型の値や一部のオブジェクトは、リテラルを使うことで簡単に定義できるようになっています。リテラルとはプログラム上で数値や文字列など、データ型の値を直接記述できるように構文として定義されたものです。"と"で囲んだ範囲が文字列リテラルで、これは文字列型のデータを表現しています。次のコードでは、"こんにちは"という文字列型のデータを初期値に持つ変数strを定義しています。"こんにちは";リテラル表現がない場合は、その値を作る関数に引数を渡して作成する形になります。そのような冗長な表現を避ける方法として、よく利用される主要な値にはリテラルが用意されています。nullまた、オブジェクトの中でもよく利用されるものに関してはリテラル表現が用意されています。正規表現これらのリテラルについて、まずはプリミティブ型から順番に見ていきます。真偽値(Boolean)真偽値にはtrueとfalseのリテラルがあります。それぞれはtrueとfalseの値を返すリテラルで、見た目どおりの意味となります。false数値(Number)数値は大きく分けて42のような整数リテラルと3.14159のような浮動小数点数リテラルがあります。整数リテラル整数リテラルには次の4種類があります。0x(または0X)の後ろに、0から9までの数字とaからfまたはAからFのアルファベットの組み合わせアルファベットの大文字・小文字の違いは値には影響しません例)0x30A2、0xEEFF0から9の数字のみで書かれた数値は、10進数として扱われます。2550bからはじまる2進数リテラルは、ビットを表現するのによく利用されています。bは2進数を表すbinaryを意味しています。10240oからはじまる8進数リテラルは、ファイルのパーミッションを表現するのによく利用されています。oは8進数を表すoctalを意味しています。511次のように、0からはじまり、0から7の数字を組み合わせた場合も8進数として扱われます。この表記は10進数と紛らわしいものであったため、ES2015で0oの8進数リテラルが新たに導入されました。modeではこの書き方は例外が発生するため、次のような8進数の書き方は避けるべきです。5110xからはじまる16進数リテラルは、文字のコードポイントやRGB値の表現などに利用されています。xは16進数を表すhexを意味しています。754を採用しています。浮動小数点数をリテラルとして書く場合には、次の2種類の表記が利用できます。含んだ数値0からはじまる浮動小数点数は、0を省略して書くことができます。0からはじまる場合でも省略せずに書いたほうが意図しない挙動を減らせるでしょう。変数名を数字からはじめることができないのは、数値リテラルと衝突してしまうからです。eは指数(exponent)を意味する記号で、eのあとには指数部の値を書きます。2e8は2×10の8乗となるので、10進数で表すと200000000となります。200000000文字列(String)文字列リテラル共通のルールとして、同じ記号で囲んだ内容を文字列として扱います。文字列リテラルとして次の3種類のリテラルがありますが、その評価結果はすべて同じ"文字列"になります。"文字列"ダブルクォートとシングルクォート"(ダブルクォート)と'(シングルクォート)はまったく同じ意味となります。PHPやRubyなどとは違い、どちらのリテラルでも評価結果は同じとなります。\'のように\(バックスラッシュ)を使ってエスケープしなければなりません。o'clock"また、文字列内部に出現しない別のクォート記号を使うことで、エスケープをせずに書くこともできます。o'clock"ダブルクォートとシングルクォートどちらも、改行をそのままでは入力できません。次のように改行を含んだ文字列は定義できないため、構文エラー(SyntaxError)となります。break改行の代わりに改行記号のエスケープシーケンス(\n)を使うことで複数行の文字列を書くことができます。"複数行の\n文字列を\n入れたい";シングルクォートとダブルクォートの文字列リテラルに改行を入れるには、エスケープシーケンスを使わないといけません。これに対してES2015から導入されたテンプレートリテラルでは、複数行の文字列を直感的に書くことができます。(バッククォート)で囲んだ範囲を文字列とするリテラルです。テンプレートリテラルでは、複数行の文字列を改行記号のエスケープシーケンス(\n)を使わずにそのまま書くことができます。囲めば、そのまま書くことができます。"複数行の\n文字列を\n入れたい"また、名前のとおりテンプレートのような機能も持っています。テンプレートリテラル内で${変数名}と書いた場合に、その変数の値を埋め込むことができます。"これは文字列です"テンプレートリテラルも他の文字列リテラルと同様に同じリテラル記号を内包したい場合は、\を使ってエスケープする必要があります。`code`"nullリテラルnullリテラルはnull値を返すリテラルです。nullは「値がない」ということを表現する値です。参照できないためReferenceErrorの例外が投げられます。null値を代入することで、null値を持つfooという変数を定義できます。これにより、fooを値がない変数として定義し、参照できるようになります。undefinedはリテラルではないプリミティブ型として紹介したundefinedはリテラルではありません。undefinedはただのグローバル変数で、undefinedという値を持っているだけです。次のように、undefinedはただのグローバル変数であるため、同じundefinedという名前のローカル変数を宣言できます。"独自の未定義値"}fn();これに対してtrue、false、nullなどはグローバル変数ではなくリテラルであるため、同じ名前の変数を定義することはできません。リテラルは変数名として利用できない予約語のようなものであるため、再定義しようとすると構文エラー(SyntaxError)となります。SyntaxErrorこのコラムでは、説明のためにundefinedというローカル変数を宣言しましたが、undefinedの再定義は非推奨です。無用な混乱を生むだけなので避けるべきです。オブジェクトリテラルJavaScriptにおいて、オブジェクトはあらゆるものの基礎となります。そのオブジェクトを作成する方法として、オブジェクトリテラルがあります。オブジェクトリテラルは{}(中カッコ)を書くことで、新しいオブジェクトを作成できます。中身が空のオブジェクトを作成オブジェクトリテラルはオブジェクトの作成と同時に中身を定義できます。中に書くことで作成と初期化が同時に行えます。いう値を持つオブジェクトを作成しています。キー名には、文字列またはSymbolを指定し、値にはプリミティブ型の値からオブジェクトまで何でも入れることができます。"value"};このとき、オブジェクトが持つキーのことをプロパティ名と呼びます。objというオブジェクトはkeyというプロパティを持っていると言います。[](ブラケット)で参照する方法があります。"value"ドット記法では、プロパティ名が変数名と同じく識別子である必要があります。そのため、次のように識別子として利用できないプロパティ名はドット記法として書くことができません。ドット記法では、数値からはじまる識別子は利用できないobject.123オブジェクトはとても重要で、これから紹介する配列や正規表現もこのオブジェクトが元となっています。詳細は「オブジェクト」の章で解説します。ここでは、オブジェクトリテラル({と})が出てきたら、新しいオブジェクトを作成しているんだなと思ってください。配列リテラルオブジェクトリテラルと並んで、よく使われるリテラルとして配列リテラルがあります。配列リテラルは[と]で値をカンマ区切りで囲み、その値を持つArrayオブジェクトを作成します。配列(Arrayオブジェクト)とは、複数の値に順序をつけて格納できるオブジェクトの一種です。配列は0からはじまるインデックス(添字)に、対応した値を保持しています。作成した配列の要素を取得するには、配列に対してarray[index]という構文で指定したインデックスの値を参照できます。"index:1"配列についての詳細は「配列」の章で解説します。正規表現リテラルJavaScriptは正規表現をリテラルで書くことができます。正規表現リテラルは/と/で正規表現のパターン文字列を囲みます。正規表現のパターン内では、+や\(バックスラッシュ)からはじまる特殊文字が特別な意味を持ちます。次のコードでは、数字にマッチする特殊文字である\dを使い、1文字以上の数字にマッチする正規表現をリテラルで表現しています。trueRegExpコンストラクタを使うことで、文字列から正規表現オブジェクトを作成できます。特殊文字の二重エスケープが必要になり直感的に書くことが難しくなります。正規表現オブジェクトについて詳しくは、「文字列」の章で紹介します。プリミティブ型とオブジェクトプリミティブ型は基本的にリテラルで表現しますが、真偽値(Boolean)、数値(Number)、文字列(String)はそれぞれオブジェクトとして表現する方法もあります。これらはプリミティブ型の値をラップしたようなオブジェクトであるためラッパーオブジェクトと呼ばれます。ラッパーオブジェクトは、new演算子と対応するコンストラクタ関数を利用して作成できます。文字列のプリミティブ型に対応するコンストラクタ関数はStringとなります。次のコードでは、Stringのラッパーオブジェクトを作成しています。ラッパーオブジェクトは、名前のとおりオブジェクトの一種であるためtypeof演算子の結果も"object"です。オブジェクトであるためlengthプロパティなどのオブジェクトが持つプロパティを参照できます。3しかし、明示的にラッパーオブジェクトを使うべき理由はありません。JavaScriptではプリミティブ型のデータに対してもオブジェクトのように参照できる仕組みがあるためです。次のコードでは、プリミティブ型の文字列データに対してもlengthプロパティへアクセスできています。3これは、プリミティブ型のデータのプロパティへアクセスする際に、対応するラッパーオブジェクトへ暗黙的に変換してからプロパティへアクセスするためです。ラッパーオブジェクトを明示的に作成するには、リテラルに比べて冗長な書き方が必要になります。このように、ラッパーオブジェクトを明示的に作成する必要はないため、常にリテラルでプリミティブ型のデータを表現することを推奨します。このラッパーオブジェクトへの暗黙的な型変換の仕組みについては「ラッパーオブジェクト」の章で解説します。現時点では、プリミティブ型のデータであってもオブジェクトのようにプロパティ(メソッドなども含む)を参照できるということだけを知っていれば問題ありません。まとめこの章では、データ型とリテラルについて学びました。"object"となるバグがありました。このバグを修正するとすでにこの挙動に依存しているコードが壊れるため、修正が見送られ現在の挙動が仕様となりました。詳しくはhttps://2ality.com/2013/10/typeof-null.htmlを参照。