# データ型とリテラル ## データ型 jsは動的型付け言語に分類され、静的型付け言語の様に変数の型はないが、文字列、数値、真偽値といった**値の型**は存在しこれらの値の型の名前を<span style="color: red; ">データ型</span>と呼ばれる。 データ型には大きく分けて **プリミティブ型**と**オブジェクト**の2つに分類される - プリミティブ型 真偽値や数値などの基本的な値の型のこと、プリミティブ型は一度作成したらその値自体を変更できない<span style="color: red; ">イミュータブル</span>の特性を持つ - オブジェクト 複数のプリミティブ型の値またはオブジェクトからなる集合のこと、その値自体を変更することができる。 ### イミューダブルとミューダブル #### イミューダブル イメージとして... 宣言した変数を後から変更した場合に、新しい値は新たに保存されたメモリ空間に保存され、前の参照先(メモリー空間)に保存された値を直接変更できるわけではない為 ```javascript= let name = "aaaa" //string型を定義と同時にメモリー空間に保存 //参照先=> 例) 2332vklsad //中身を変更 name = "bbbb" //変更前のnameを直接的に変更しているのではなく参照先の値を変更 //参照先=> 例) 2332vklsad から sakdfjklに変更された!! ``` #### ミューダブル オブジェクトへの何かしらの操作は値ではなく値の参照先を経由して操作されるため値の変更ができている。 ```javascript= let arr = [1,2,3] //arrの参照先はal3sdkfj arr[0] = 2 //0番目の要素を2に変更 //al3sdkfjを参照している為データの変更することができる。 ``` **プリミティブの種類(7つ)** - 真偽値 trueまたfalse - 数値(Number) 42や3.14などの数値 - 巨大な数値 9007199254740992nなどの任意精度の整数のデータ型 - 文字列(String): "JavaScript" などの文字列のデータ型 - undefined: 値が未定義であることを意味するデータ型 - null: 値が存在しないことを意味するデータ型 - シンボル(Symbol): ES2015から追加された一意で不変な値のデータ型 **オブジェクト** - プリミティブ型以外のデータ - オブジェクト、配列、関数、クラス、正規表現、Dateなど プリミティブ型でないものは、オブジェクト type of演算子を使うことで次のようにデータ型を調べることができる。 ```javascript console.log(typeof true);// => "boolean" console.log(typeof 42); // => "number" console.log(typeof ["配列"]); // => "object" console.log(typeof { "key": "value" }); // => "object" ``` プリミティブな値はtype ofを使用するとその値のデータ型を返してくれる オブジェクトに分類される値は"object"を返す [](配列と)と{}(オブジェクト)はどちらも"object"と出力されるため正しく判定することができないが関数はオブジェクトの中でも特別扱いされているためtypeofの評価結果としてはfunctionが出力される。 ## リテラル リテラルとはプログラム上で数値や文字列などデータ型の値を直接記載できるように構文として定義されたものを言う。 ```javascript // "と"で囲んだ範囲が文字列リテラル const str = "こんにちは"; ``` プリミティブ型でよく使われるリテラル - 真偽値 - 数値 - 文字列 - null オブジェクトでよく使われるリテラル - オブジェクト - 配列 - 正規表現 --- ### 真偽値(boolean) 真偽値の返す値としてtrueとfalseがの値を返すリテラル ```javascript! true; // => true false; // => false ``` --- ### Number型 数値を扱うためのデータ型JavaScriptのNumber型では、整数も少数も同じNumber型として扱うことのできる 正確に扱うことができる数値は2の53乗から1引いた値 3.14159のような浮動小数点数リテラルがある #### 整数リテラル 10進数、2進数、8進数、16進数の4種類が存在する。 - 10進数: 複数の数字を組み合わせ先頭に0の記載を行うと場合によっては8進数として扱われる時がある。 ```javascript! console.log(0100) //8進数の100で10進数の値として出力される=>64 console.log(74) //=>74 ``` 例)0,2,10 - 2進数: 0b(または0B)の後ろに、0または1の数字の組み合わせ 例)0b0、0b10、0b1010 - 8進数: 0oで始める(または0O)0か7の数字を使用する 0o は数字のゼロと小文字アルファベットのo 例)0o644、0o777 - 16進数: 0x(または0X)の後ろに、0から9までの数字とaからfまたはAからFのアルファベットの組み合わせアルファベットの大文字・小文字の違いは値には影響しません 例)0x30A2、0xEEFF | 名前 | 表現例 | 用途 | | -------- | -------- | -------- | | 10進数|42 | 数値| | 2進数| 0b0001|ビット演算 | | 8進数| 0o777| ファイルのパーミッション| | 16進数| 0xEEFF| 文字のコードポイント,RGB| #### 浮動小数点のリテラル - 3.14159 のような .(ドット)を含んだ数値 - 2e8 のような e または E を含んだ数値 0から始まる場合は0を省略することができる。 ```javascript! .123 // => 0.123 ``` .をオブジェクトとして扱う機会が多いため0から始まる場合でも省略をせずに書いたほうがバグを減らせる eは指数(exponent)を意味する記号で、eのあとには指数部を表すことができる。 2e8の場合だと2☓10の8乗と表現することができる。 ```javascript! 2e8; // => 200000000 ``` #### BigInt型 Number型で取り扱うことのできない大きな数値を扱うためのデータ型 数値リテラルが正確に表せる最大の数値よりも大きな値を扱いたいとき(9007199254740991) は末尾にnをつける ```javascript! console.log(1n); // => 1n // 2^53-1より大きな値も扱える console.log(9007199254740992n); // => 9007199254740992n ``` #### Numeric Separators 数値が大きくなるほど、桁数の見間違いが発生してしまうので_区切り文字で入れてあげると見と視認性が向上する 数値リテラルを評価する際に_は単純に無視される ```javascript! 1000000000000 1_000_000_000_000; ``` Numeric Separatorsは数値リテラルである整数、浮動小数点、BigIntのリテラル内でのみ使用可 _はリテラルの先頭や最後に追加することができない ```javascript! _123; // 変数として評価される 3._14; // => SyntaxError 0x52_; // => SyntaxError 1234n_; // => SyntaxError ``` --- ### 文字列 文字列リテラル共通のルールとして同じ記号囲んだ内容を文字列として扱う、文字列の場合だと3種類のリテラルがある。その評価結果はすべて同じ文字列として出力される。 ```javascript! console.log("文字列"); // => "文字列" console.log('文字列'); // => "文字列" console.log(`文字列`); // => "文字列" ``` jsではダブルクォート""、シングルクォート''は他のrubyやphpとは異なりどちらで書いた場合も全く同じ結果となる 文字列リテラルは同じ記号で囲む必要があるため同じ記号が出現した場合は、 \'のように\(バックスラッシュ)を使ってエスケープの必要がある ```javascript '8 o\'clock'; // => "8 o'clock" ``` ダブルクォート、シングルクォートはどちらも改行をそのままでは入力できはい ```javascript! "複数行の 文字列を 入れたい"; // => SyntaxError: "" string literal contains an unescaped line break ``` 改行の代わりに改行記号をエスケープシーケンスを(\n)を使用することで複数の文字列を書くことができる ```javascript! 複数行の\n文字列を\n入れたい"; 複数行の 文字列を 入れたい ``` #### テンプレートリテラル バッククォートで囲んだ範囲を文字列とするリテラル 改行記号のエスケープシーケンスの記載は不要になる ```javascript `複数行の 文字列を 入れたい`; ``` テンプレートのような機能を持っているためテンプレートリテラル内で${変数}と書いた場合変数の値をうめこむことができる ```javascript const str = "文字列"; console.log(`これは${str}です`); // => "これは文字列です" ``` 他の文字列リテラル記号と同様に同じリテラル記号を内側で記載したいときはエスケープしてあげる必要がある。 ```javascript `This is \`code\`` ``` --- ### nullリテラル nullリテラルはnull値を返すリテラル。 nullは値がないときを表す値。 値がないことを表現したい場合は任意の変数にnullを明示的に代入することで、null値を持つ変数を定義できる ```javascript! const foo = null; console.log(foo); // => null ``` --- **undefinedはリテラルではない** プリミティブ型のundifinedはリテラルではなく、グローバル変数でundifinedという値をもっているだけ undefinedはただのグローバル変数であるため、同じundefinedという名前のローカル変数を宣言可 ```javascript function fn(){ const undefined = "独自の未定義値"; // undefinedという名前の変数をエラーなく定義できる console.log(undefined); // => "独自の未定義値" } fn(); ``` true、false,nullなどはグローバル変数ではなくリテラルであるため変数を定義することはできない --- ## オブジェクトリテラル jsにおいてオブジェクトはあらゆるものの基礎となり作成方法は{}オブジェクトリテラルを使用して新しいオブジェクトを作成することができる。 ```javascri const obj = {} //中身がからのオブジェクトを作成 ``` オブジェクトリテラルは作成と当時に:を{}の中に記載することで定義を行うことができる。 ```javascript! const obj = { "key": "value" }; ``` objというオブジェクトはkeyという<span style="color: red; ">プロパティー</span>を持っている。 objのkeyを参照する方法 - .(ドット)で繋いで参照する - []ブラケットを使って参照する ```javascript! const obj = { "key": "value", 123: 123, }; // ドット記法 console.log(obj.key); // => "value" // ブラケット記法 console.log(obj["key"]); // => "value" console.log(obj["123"]); // => "123" console.log(obj[123]); // => "123" // NG: ドット記法では、数値からはじまる識別子は利用できない object.123 ``` ## 配列リテラル 配列[]で値を区切りで囲み、その値を持つarrayオブジェクトを作成する。 配列は複数の値を順番に格納できるオブジェクトの一種 ```javascript! const emptyArray = []; // 空の配列を作成 const array = [1, 2, 3]; // 値を持った配列を作成 ``` 配列は0から始まるインデックス番号を指定することによって対応した値を参照することができる 配列に対してarray[index]で値の参照をすることができる。 ```javascript! const array = ["index:0", "index:1", "index:2"]; // 0番目の要素を参照 console.log(array[0]); // => "index:0" // 1番目の要素を参照 console.log(array[1]); // => "index:1" ``` ## 正規表現 jsでは正規表現をリテラルでかくことができる、 記載方法は/と/(スラッシュ)で表現することができる >正規表現とは、ある特定のパターンを持つ文字列を指定する表記法の一つ。文字列の検索や置換、抽出などを行う際の対象の指定などのために用いられる。 正規表現のパターン内では+などの特定の記号や\バックスラッシュから始まる特殊文字が特別な意味をを持つ ```javascript! \d 0~9までの数字 const numberRegExp = /\d/; console.log(numberRegExp.test(123)); //true ``` ## プリミティブ型とオブジェクト プリミティブ方は基本的にはリテラルで表現するが、真偽値や数値、文字列をオブジェクトとして表現する方法もありこれらのプリミティブの値をラップしたオブジェクトであるため<span style="color: red; ">ラッパーオブジェクト</span>と呼ばれる ラッパーオブジェクトはnew演算子と対応するコンストラクタ関数を利用して作成できる 文字列を作りたいときは(Stringでコンストラクタ関数を使用する) stringでコンストラクター関数を使用してラッパーオブジェクトを作る流れ ```javascript! // 文字列をラップしたStringラッパーオブジェクト const str = new String("文字列"); // ラッパーオブジェクトは"object"型のデータ console.log(typeof str); // => "object" // Stringオブジェクトの`length`プロパティは文字列の長さを返す console.log(str.length); // => 3 ``` プリミティブ型のデータもオブジェクトのように参照する仕組みがあるため 基本的にはラッパーオブジェクトを使う理由はありません。 ```javascript! // プリミティブ型の文字列データ const str = "文字列"; // プリミティブ型の文字列は"string"型のデータ console.log(typeof str); // => "string" // プリミティブ型の文字列も`length`プロパティを参照できる console.log(str.length); // => 3 ``` lenghtのようなオブジェクトが持つプロパティーにアクセスできるのも プリミティブ型のデータのプロパティーにアクセスする際にラッパーオブジェクトへ暗黙的な型変換が行われてるため 明示的にラッパーオブジェクトを作成するには冗長な書き方が必要になるため、常にリテラルでプリミティブ型のデータを表現することが推奨されている。 ## この章のまとめ - 7種類のプリミティブ型とオブジェクトがある - リテラルはデータ型の値を直接記述できる構文として定義されたもの - プリミティブ型の真偽値、数値、文字列、nullはリテラル表現がある - オブジェクト型のオブジェクト、配列、正規表現にはリテラル表現がある - プリミティブ型のデータでもプロパティアクセスができる ## みなさんも何かあれば!!! ### リテラルとは ソースコード内にべた書きした文字や数字のこと。(literal: 文字の、文字通りの) **例** ```javascript const name = "ピヨ太" // 「ピヨ太」がリテラル const age = 18 // 「18」がリテラル ``` [参考リンク](https://wa3.i-3-i.info/word15346.html) --- ### JavaScriptのBigInt BigIntを使用すると、53bit(2の53乗)である「 9007199254740992 」より大きな値を扱うことが可能となる。 [javascript BigIntを使用する](https://mebee.info/2020/10/29/post-21027/) --- ### Railsのbigint 4バイトの整数の最大値は (2の31乗 - 1) = 2,147,483,647 これより大きな値を扱うことが出来る。 [PostgreSQLのINTEGERの最大値は2,147,483,647!](https://salumarine.com/max-integer-value-is-2147483647-in-postgresql/) Railsでテーブルを作成する際、DBがPostgreSQLやMySQLの場合は`id`が`bigint`になる。 (SQLiteは`integer`) レコードの数が膨大になり、足りなくなるため。 [Railsガイド](https://railsguides.jp/active_record_basics.html#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%AB) [Railsのmigrationでbigintを使う](https://qiita.com/naokishizuka/items/e51b5ea9ec56dd0471f7) [Rubyと仲良くなりたい٩( 'ω' )و](https://chinatz.hatenablog.com/entry/2018/07/20/210000)