JavaScript入門 変数とデータ型の解説
JavaScriptの変数について解説しています。
変数
変数宣言
JavaScript で変数を使うには、変数の宣言を行う必要があります。変数の宣言方法はプログラミング言語の種類によってことなりますが、JavaScript の場合はletというキーワードで変数を宣言します。変数を宣言することではじめて、変数名で値を管理できるようになります。
let 変数名 = 値;
変数名(識別子とも言います)はある程度きまった形式で命名しますが、基本的に「半角英数字」で命名します。
サンプル
let hello = "おはよう";
window.alert( hello );
このプログラムでは、変数に値を代入するときに等号(=)を使っています。プログラムにおける等号(=)は、値の代入を表します。
定数
値を変更できない変数を定数と呼びます。定数は、宣言したあとに値の再代入を行えません。この性質から、定数は、あとで変更されては困る値を扱うときに使用します。定数を宣言するには、constというキーワードを使用します。
定数の宣言方法
const 変数名 = 値;
定数は上書き不可能であることから、変数と区別して扱うために、定数名がすべて大文字で表記される場合があります。JavaScript の場合はgreetingのように定数に対しても小文字表記を使うケースがより一般的です。
const CONST_VAL = "ABC";
識別子の命名規則
変数名は、識別子と呼ぶこともあります。識別子の命名には、ある一定のルールがあり、識別子の命名規則に従わない場合にはJavaScript の実行時にエラーが発生します。
- 予約語は使用できない。
- 1文字目は、必ずアルファベットかアンダースコア(_)かドル記号($)から始めなくてはならない。
- 2文字目以降は数値(0-9)も使用可能
- 大文字と小文字は区別される
- Unicodeのアルファベットや\uといった特殊な文字列(エスケープシーケンス)も使用可能。しかし、バグの元になるため特別な理由があるとき以外は使用しない
わかりやすい識別子
ソフトウェアの開発は一般的にはチームで行うことが多いです。そのため、「その変数はどういう意図のものなのか」を相手に伝える意味で、識別子の命名は非常に大事です。
たとえば、次のコードがあったとします。
let a= 1000;
console.log( a * 1.1 );
>1100
このコードから「コードを書いた開発者の意図」がわかるひとは少ないでしょう。次のように書かれていたらどうでしょう。税込み金額を計算しているということがコードを見ただけでわかります。ソースコード内に直接、値を詰めこんで意味や意図がわからないソースコードを「マジックナンバー」と言います。
const TAX_RATE = 1.1;
let productPrice = 1000;
console.log( productPrice * TAX_RATE );
データ型
プログラムで扱うデータにはいくつか種類があります。そのデータの種類の事を「データ型」といいます。JavaScript には8種類のデータ型があります。
データ型の種類
データ型 | 値 | |
---|---|---|
String | 文字列 | シングルクォート(’)、ダブルクォート(”)、バッククォート(`)で囲んだ文字列 |
Number | 数値 | -(253 – 1)~253 – 1 の数値(整数または浮動小数点数) ※256 – 1 = 9007199254740991 |
BigInt | 巨大な整数 | 任意の大きさの整数値 |
Bolean | 真偽値 | true/false |
null | ヌル | null ※値が空(存在しない)ことを表す |
undefined | 未定義 | undefined ※値が未定義であることを表す |
Symbol | シンボル | 一意で普遍な値 |
Object | オブジェクト | キーと値を対で格納する入れ物 |
変数に格納される値は、データ型のいずれかの型に一致することになります。また、これら8つのデータ型は、大きく次の2つに分類されます。
- プリミティブ型:オブジェクト以外のデータ型
- 非プリミティブ型(複合型:オブジェクト)
リテラル
データ型の値をコードで直接記述するための「構文をリテラル」と呼びます。プログラムが解釈可能なリテラルを使うことによって、文字列や数値などの固定値をコードで使用できます。
文字列リテラル
シングルクォート(’)、ダブルクォート(”)で囲むことで文字列を表します。ES6からバッククォート()も使用できます。(
`は、文字列中に${変数名}の形式で変数や定数を挿入できます。
'おはよう'
"おはよう"
`おはよう${name}`
数値リテラル
数値を表すときに使うリテラル(0~9)です。10進数以外でも表現できます。
150
-43
1.1
BigIntリテラル
数値の後ろに付くnは、BigInt型のリテラルを示す記号です。
12345678910n;
真偽値リテラル
true、falseは真偽値を表すリテラルです。
true
false
nullリテラル
変数が参照を保持していないことを表すリテラルです。
null
オブジェクトリテラル
新しいオブジェクトの作成を行います。{ }で表します。
{
name: "山田太郎",
age: 20
}
配列リテラル
新しい配列の作成を行います。[]で表します。
[0,1,2,3,4,5]
正規表現リテラル
新しいRegExpオブジェクトの作成を行います。
/ab+c/
関数リテラル
新しい関数の宣言を行います。functionというキーワードを使います。
let abc = function (){
・・・
};
プリミティブ型
文字列(String)
シングルクォート(’)、ダブルクォート(”)、バッククォート(`)を使います。文字列同士のは、プラス(+)の演算子を使って結合できます。
'おはよう'
"おはよう"
`おはよう${name}`
文字列の結合
console.log( "おはよう" + '太郎' );
>おはよう太郎!
シングルクォートやダブルクォートを文字列に含めたい場合は、文字列に含めたいクォートの種類とは別のクォートで全体を囲みます。
console.log( "おはよう'太郎'" );
>おはよう'太郎'
ダブルクォートの中にダブルクォートを使う場合は、バックスラッシュ(\)を使います。
console.log( "おはよう\"太郎\"" );
>おはよう"太郎"
このようにバックスラッシュに続けてダブルクォートを使うことで、ダブルクォートを文字として表示できます。(シングルクォートでも同様です)。このようなバックスラッシュに続く特殊な文字列をエスケープシーケンスと言います。
テンプレートリテラル
ES6から、文字列リテラルの中に変数や定数を挿入できるテンプレートリテラルを使えるようになりました。テンプレートリテラルを使う場合には、バッククォート()で文字列を囲みます。また、テンプレートリテラルを使った文字列定義では、次のように
“内で変数を${}で囲むことで、変数の値を文字列に挿入できます。
let fullName = "山田太郎";
console.log( "おはよう${ fullName }" );
>おはよう山田太郎
数値(Number)
JavaScript では数値はNumber型で表します。Number型は、-(253-1)から253-1までの数値を表現できます。また、数値の先頭に0b、0o、0xなどを付けることによって、10進数以外も表現できます。
Nimber型で使用可能な数値の表現形式
名称 | 表現形式 | JavaScript での表記例 |
---|---|---|
10進数 | 0~9の10種類の数字で数値を表現 | 1234。0.5、.5 |
2進数 | 0、1の2種類の数字で数値を表現 | 0b11、0011、011 |
8進数 | 0~7の8種類の数字で数値を表現 | 0o11、0O11、011 |
16進数 | 0~9の10種類の数字とA~Fの6種類のアルファベットで数値を表現 | 0x11、0X11 |
10進数
10進数で数値を表す場合には、0以外の数値から始めます(0から始めた場合には、8進数と認識されるので注意してください)。また、次のように、浮動小数点リテラル(.)を使うことで、小数点以下の数値を表現できます。この場合には、0.5のように0からはじめても10進数と認識されます。なお、浮動小数点の先頭の0は省略することもできます。
浮動小数点の記述例
console.log( 123 + 0.5 );
>123.5
console.log( 123 + .5 );
>123.5
また、数値にeに続けて数値を記入した場合には、10数値を表します。
eに続けて数値を記入した場合
console.log( 3e4 );
>30000
2進数
先頭に0bまたは0Bを付けることで、2進数で数値を表します。
2進数の記述例
console.log( 0b11 );
>3 //10進数では3と同値
8進数
先頭に0o、0O(ゼロオー)または0を付けることで、8進数で数値を表します。
8進数の記述例
console.log( 0o11 );
>9 //10進数では9と同値
16進数
先頭に0xまたは0Xを付けて、数字の0~9、アルファベットのa~f(大文字でも可)を続けることで、16進数で数値を表します。
16進数の記述例
console.log( 0x11 );
>17 //10進数では17と同値
プログラム言語によっては、整数と小数点でデータ型が異なり、直接計算することができないものもありますが、JavaScript の場合、整数も浮動小数点のどちらもNumber型として扱われます。そのため、整数と小数点混在した計算が出来ます。
let intNumber = 100;
let flootNumber = 0.5;
console.log( intNumber + flootNumber );
>100.5
BigInt
BigIntは、任意の精度で整数値を扱える型です。数値の松尾にnを付けることで、BigInt型の数値として定義できます。Number型は、-2(253 -1)から253 – 1までの数値しか表せず、その範囲を超える数値の場合には値が丸め込まれます。一方、BigIntの場合には、Number型では表せない値の範囲を表現できます。
//Number型では正常処理の範囲外のため、誤った値が表示される
console.log( 2 ** 53 +1 );
>9007199254740992
//BigInt型であれば問題なく表示できる
console.log( 2n ** 53n +1n );
>9007199254740933n //
なお、BigInt型とNumber型は、混在して使用はできません。また、BigIntは、あくまで整数値を表す型なので小数点以下は切り捨てられます。
真偽値(Boolean)
真偽値は、trueまたはfalseという値を取ります。trueの場合には、真、falseの場合には偽ということになります。if文などの条件文とあわせて使われます。
let isHungry = true;
if( isHungry ){
console.log( "Yes" );
}
>Yes
null
nullは、参照を保持していないことを表します。すなわち、「変数が空である」ことを意図的に表す特別なリテラル。変数には値が格納されているメモリに対する参照が格納されますが、nullはその参照が空であることを表しています。
let strList = null;
undefined
nullは参照を保持していないことを表しますが、undefinedは変数が未定義であることを表しています。変数を宣言するときに値を代入しない場合には、undefinedがプログラムによって自動的に設定されます。nullは基本的に明示的に設定しない限り、変数に設定されることはありませんが、「undefinedはプログラムによって自動的に設定」されます。
let name;
console.log( name );
>undefined
nullは変数が空であることを表すリテラルですが、undefinedは値が未定義とうい意味の特別な値です。両者は似たような意味のデータ型ですが、使い分けは次のようにします。undefinedは、変数宣言時に値を設定しない時にプログラムによって自動的に設定される値です。一方、nullは空であることを明示的に設定したい場合に使用します。変数が空であることを意図的にしたい場合は、nullを使用します。
オブジェクト
JavaScript のオブジェクトは、使用頻度も高く、JavaScript の仕組みの根幹にも深く関わっています。
オブジェクトの初期化
JavaScript におけるオブジェクトとは、変数を管理する入れ物のようなものです。変数宣言では変数ごとに値の場所(アドレス)を管理していましたが、オブジェクトでは複数の値を1つのまとまり(構造体)として管理できます。オブジェクトを使うには、まずオブジェクトの初期化を行います。初期化とは、何らかの機能を使用可能な状態にすることです。つまり、オブジェクトの初期化は、「オブジェクトを使用可能な状態にすること」です。
オブジェクトの初期化
let オブジェクトの名前 = {
プロパティ1:値1
プロパティ2:値2
プロパティ3:値3
}
{~}の部分は、オブジェクトリテラルと呼びます。この{~}の中に、プロパティ(またはキーと呼びます)と値を、コロン(:)で区切ってペアで格納していきます。また、オブジェクトの初期化時に留意すべき点があります。
オブジェクトのプロパティ(キー)には、文字列を使う(大文字・小文字を区別)。オブジェクトの値には、すべてのデータ型の値を使うことができる。
オブジェクトの値の取得や変更を行いたい場合は、次の2つの方法があります。
ドット記法
ドット記法では、オブジェクトとプロパティをドットでつなぐことでオブジェクトの値の取得・変更ができます。
オブジェクト名.プロパティ名
ドット記法でプロパティにアクセス
let person = {
name : { first: "山田", last: "太郎"},
age: 18
};
console.log( person.age ); //ageプロパティの値の取得
>18
console.log( person.name.last ); //nameプロパティに設定されたオブジェクトのlastプロパティの値を取得
>太郎
person.name.last = "次郎"; //lastプロパティの値変更
person.gender = "男"; //genderプロパティと値の追加
person.family = { wife: "花子",child:"三郎" }; //familyプロパティに他のオブジェクトを追加
console.log( person.family.wife ); //追加したオブジェクトのプロパティを確認
>花子
console.log( person ); //オブジェクトの中身を確認
>{age:18, family:{ wife: "花子", child: "三郎" },gender : "男", name { first: "山田" ,last: "太郎" }}
ドット記法で値を取得する場合には、ドット(.)をはさんでオブジェクトとプロパティを記述します。また、値を変更した胃場合には、代入演算子(=)で値を代入できます。オブジェクトのプロパティにさらにオブジェクトを追加したい場合には、person.name.lastのようにドットをつなげます。注意点としては、ドット(.)に続くキーワードは、必ず、プロパティ名を直接指定することです。
ブラケット記法
ブラケット記法では、オブジェクトの後ろに[]を続けて、その中に文字列でプロパティ名を記述します。
ブラケット記法
オブジェクト名["プロパティ名"]
ブラケット記法の使用例
let person = {
name : { first: "山田", last: "太郎"},
age: 18
};
console.log( person["age"] ); //ageプロパティの値の取得
>18
console.log( person["name"]["last"] ); //nameプロパティに設定されたオブジェクトのlastプロパティの値を取得
>太郎
person["name"]["last"] = "次郎"; //lastプロパティの値変更
person["gender"] = "男"; //genderプロパティと値の追加
person["family"] = { wife: "花子",child:"三郎" }; //familyプロパティに他のオブジェクトを追加
console.log( person["family"]["wife"] ); //追加したオブジェクトのプロパティを確認
>花子
console.log( person ); //オブジェクトの中身を確認
>{age:18, family:{ wife: "花子", child: "三郎" },gender : "男", name { first: "山田" ,last: "太郎" }}
ブラケット記法の場合、ダブルクォートで囲まれた文字列でプロパティ名を指定します。また、ブラケット記法の場合には、[]の中に変数を記述できるため、変数を使って値を取得できます。
変数を使ったプロパティ名の指定
const members = {
member1: "太郎",
member2: "次郎",
}
const keyBose = "member";
console.log( members[ keyBase + "1" ] ); //文字列が結合されてmember1になる
>太郎
console.log( members[ keyBase + "2" ] ); //文字列が結合されてmember2になる
>次郎
このようにブラケット記法では、[]内で変数を使って文字列を整形し、その文字列(プロパティ名)に一致する値を取得できます。
変数を使ってプロパティを指定する場合には、ブラケット記法を使用。それ以外の時は、短く記述できるドット記法を使用します。
オブジェクトリテラル内のブラケット記法
ES6から、オブジェクトリテラルによる初期化の際にブラケット記法を使用してプロパティ名を定義できます。
const keyBase = "member";
let members = {
[ keyBase + "1" ]: "太郎",
[ keyBase + "2" ]: "次郎",
}
console.log( members );
>{ member1:"太郎",member2:"次郎" }
プロパティの削除
オブジェクトのプロパティを削除するときには、delete演算子を使います。
deleteの記法
//ドット記法
delete オブジェクト.プロパティ;
//ブラケット記法
delete オブジェクト["プロパティ"];
deleteの使用例
let person = {
name: { first: "山田", last: "太郎"},
oge: 18
};
console.log( person.age );
>18
delete person.age; //ageプロパティを削除
console.log( person.age );
>undefined //プロパティが見つからないためundefinedが取得
メソッド
オブジェクトでは、特定の処理を行う機能を追加したい場合、関数を登録できます。また、オブジェクトに保持される関数は、メソッドと呼びます。
//オブジェクトの初期化時にメソッドを定義
let オブジェクト = {
プロパティ: function ( [引数] ){ 関数の処理 }
}
//既存のオブジェクトにメソッドを追加
オブジェクト.プロパティ = function( [ 引数 ] ){ 関数の処理 }
//メソッドの実行
オブジェクト.プロパティ( [引数] ); //メソッドの実行時には、末尾に()を付ける
メソッドの記述例
let person = {
hello: function() { console.log( "はろー" ); }
}
person.hello();
>ハロー
person.bye = function() { console.log( "バイバイ" ); }
person.bye();
>バイバイ
person.hello = function() { console.log( "Hello" ); } //メソッドは上書きすることも可能
person.hello();
>Hello
オブジェクトリテラル内の省略記法
ES6から、オブジェクトリテラル内でメソッドを記述する際に省略記法を使うことができます。
let person = {
hello() { console.log( "はろー" ); } //hello: function() {}を省略した記述
}
person.hello();
すでに宣言済みの変数や関数の識別子を、そのままオブジェクトのプロパティ名として値を設定することもできます。
lete val = 10; //変数の宣言
function fn() {} //関数の宣言
const obj = {
val, //「val: val」を省略した記述
fn //「fn: fn」を省略した記述
}
console.log( obj );
>{ val: 10, fn : function() {} }
シンボル(Symbol)
シンボル(Symbol)は、ES6で追加された非常に特殊な型です。シンボル型はプリミティブ型に分類されます。シンボルは、オブジェクトのプロパティに設定するための一意の値を生成するときに使います。「一意」とは、決して他の値と重複しないことが担保されていることを意味します。そのため、シンボルを使って設定したプロパティは、決して他のプロパティと重複することがありません。
シンボルの定義方法
let 変数名 = Symbol( ["ラベル"] );
ラベル:コンソールでデバックするときに表示されるラベル名。ラベル名が同じでも、シンボルの値は異なる点に注意
シンボルを定義するには、Symbol()を実行します。このとき、ラベルを渡すことができますが、ラベルの値が同じでも生成される値は異なります。ラベルは、あくまでコンソール上でシンボルを区別するための目印です。
シンボルに渡すラベルは目印
console.log( Symbol() );
>Symbol() //どのシンボルかわからない
console.log( Symbol( "ラベルは目印" ) );
>Symbol( ラベルは目印 ) //どのシンボルかわかる
シンボルを使ってプロパティを指定する場合は、必ず「ブラケット記法」を使用する必要があります。
let mySymbl1 = Symbol(); //あるSymbolの値
let mySymbl2 = Symbol(); //別のSymbolの値
const obj = {
[ mySymbl1 ]: "値1", //シンボルをキーにプロパティを定義
[ mySymbl2 ]() { consol.log( "こんにちは" ); }
}
console.log( obj[ mySymbl1 ] );
>値1
obj[ mySymbl2 ]();
>こんにちは
JavaScript のデータ型の特徴
JavaScript はプログラム実行時に値が設定された時点で自動的に決定される「動的型付け言語」になります。動的型付け言語は、変数の宣言時にデータ型の定義が自動的に行われるため、記述としては簡素になります。一方、プログラムが大きくなるとバグが混入しやすくなり、パフォーマンスについても「静的型付け言語」と比較して遅くなります。
近年、データ型の定義が可能な静的型付け言語を求める声が大きくなりました。そこで注目されているのが「TypeScript」というプログラミング言語です。TypeScriptはJavaScript に変換可能なプログラミング言語で、データ型の定義まで行えるようになっています。そのため、大規模なプログラミングを行う場合に、JavaScript の代わりに使われることがあります。TypeScriptで書かれたコードをJavaScriptのコードに変換するような処理を「トランスパイル」と言います。
データ型の確認方法
JavaScript でデータ型を確認するには、typeofという演算子を使用します。
console.log( typeof "hello" );
>string
console.log( typeof 10 );
>number
console.log( typeof 10n );
>bigint
console.log( typeof true );
>boolean
console.log( typeof undefined );
>undefined
console.log( typeof typeof { } );
>object
console.log( typeof null ); //nullはオブジェクトを返すので注意が必要です
>object
console.log( typeof Symbol() );
>symbol
明示的な型変換
データ型を他のデータ型に変換することを「型変換」と呼びます。JavaScript では、明示的に型変換を行う方法が関数として用意されています。
明示的は型変換
関数 | 用途 | 例 | 結果 |
---|---|---|---|
Number( 値 ) | 数値へ変換する | Number( “1” ) | 1 |
Number( “hello” ) | NaN | ||
Number( “true” ) | 1 | ||
Number( “false” ) | 0 | ||
Boolean( 値 ) | 真偽値へ変換する | Boolean(1) | true |
Boolean(0) | false | ||
String( 値 ) | 文字列へ変換する | String(1) | “1” |
String(true) | “true” | ||
BigInt( 値 ) | BigInt型へ変換する | BigInt( “20” ) | 20n |
BigInt( true ) | 1n |
データ型の変換が必要なケース
数値の1と文字列の1が混在している場合、開発者は数値の足し算を行いたかったのかもしれませんが、JavaScript では文字列の結合と判断します。このような場合、データの型変換が必要になります
console.log( 1 + "1" );
>"11"
//データの型変換
console.log( 1 + Number("1") );
>2
数値の1と文字列の”1″を等価演算子(===)で比較した場合、値の比較と型の比較を行います。以下の場合は型情報が数値型、文字列型のように異なるため、結果はfalseになります。
const num = 1;
const str = "1";
console.log( num === str );
>false
暗黙的な型変換
暗黙的な型変換とは、変数が呼び出された状況によって「型情報が自動的に変換されること」を指します。
暗黙的な型変換のケース
console.log( 1 + "2" );
>"12"
1つの文の中で数値と文字列が加算演算子(+)によって、数値と文字列が混在した場合には、加算演算子は数値を文字列に暗黙的に変換したあと、文字列として結合します。JavaScript では、1つの文に複数の「データ型の値が含まれる場合は、型情報を統一」して処理を行います。
減算演算子の場合は数値として統一される
console.log( 2 - "1" );
>1